fix(compiler): support directive inputs with interpolations on <ng-template>
s (#35984)
Prior to this commit, Ivy compiler didn't handle directive inputs with interpolations located on `<ng-template>` elements (e.g. `<ng-template dir="{{ field }}">`). That was the case for regular inputs as well as inputs that should be processed via i18n subsystem (e.g. `<ng-template i18n-dir dir="Hello {{ name }}">`). This commit adds support for such expressions for explicit `<ng-template>`s as well as a number of tests to confirm the behavior. Fixes #35752. PR Close #35984
This commit is contained in:
@ -341,6 +341,78 @@ describe('directives', () => {
|
||||
|
||||
});
|
||||
|
||||
describe('inputs', () => {
|
||||
it('should allow directive inputs (as a prop binding) on <ng-template>', () => {
|
||||
let dirInstance: WithInput;
|
||||
@Directive({selector: '[dir]'})
|
||||
class WithInput {
|
||||
constructor() { dirInstance = this; }
|
||||
@Input() dir: string = '';
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
template: '<ng-template [dir]="message"></ng-template>',
|
||||
})
|
||||
class TestComp {
|
||||
message = 'Hello';
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [TestComp, WithInput]});
|
||||
const fixture = TestBed.createComponent(TestComp);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(dirInstance !.dir).toBe('Hello');
|
||||
});
|
||||
|
||||
it('should allow directive inputs (as an interpolated prop) on <ng-template>', () => {
|
||||
let dirInstance: WithInput;
|
||||
@Directive({selector: '[dir]'})
|
||||
class WithInput {
|
||||
constructor() { dirInstance = this; }
|
||||
@Input() dir: string = '';
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
template: '<ng-template dir="{{ message }}"></ng-template>',
|
||||
})
|
||||
class TestComp {
|
||||
message = 'Hello';
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [TestComp, WithInput]});
|
||||
const fixture = TestBed.createComponent(TestComp);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(dirInstance !.dir).toBe('Hello');
|
||||
});
|
||||
|
||||
it('should allow directive inputs (as an interpolated prop) on <ng-template> with structural directives',
|
||||
() => {
|
||||
let dirInstance: WithInput;
|
||||
@Directive({selector: '[dir]'})
|
||||
class WithInput {
|
||||
constructor() { dirInstance = this; }
|
||||
@Input() dir: string = '';
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
template: '<ng-template *ngIf="true" dir="{{ message }}"></ng-template>',
|
||||
})
|
||||
class TestComp {
|
||||
message = 'Hello';
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [TestComp, WithInput]});
|
||||
const fixture = TestBed.createComponent(TestComp);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(dirInstance !.dir).toBe('Hello');
|
||||
});
|
||||
});
|
||||
|
||||
describe('outputs', () => {
|
||||
@Directive({selector: '[out]'})
|
||||
class TestDir {
|
||||
|
@ -1423,6 +1423,58 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
|
||||
expect(titleDirInstances[0].title).toBe('Bonjour');
|
||||
});
|
||||
|
||||
it('should allow directive inputs (as an interpolated prop) on <ng-template>', () => {
|
||||
loadTranslations({[computeMsgId('Hello {$INTERPOLATION}')]: 'Bonjour {$INTERPOLATION}'});
|
||||
|
||||
let dirInstance: WithInput;
|
||||
@Directive({selector: '[dir]'})
|
||||
class WithInput {
|
||||
constructor() { dirInstance = this; }
|
||||
@Input() dir: string = '';
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
template: '<ng-template i18n-dir dir="Hello {{ name }}"></ng-template>',
|
||||
})
|
||||
class TestComp {
|
||||
name = 'Angular';
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [TestComp, WithInput]});
|
||||
const fixture = TestBed.createComponent(TestComp);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(dirInstance !.dir).toBe('Bonjour Angular');
|
||||
});
|
||||
|
||||
it('should allow directive inputs (as interpolated props)' +
|
||||
'on <ng-template> with structural directives present',
|
||||
() => {
|
||||
loadTranslations({[computeMsgId('Hello {$INTERPOLATION}')]: 'Bonjour {$INTERPOLATION}'});
|
||||
|
||||
let dirInstance: WithInput;
|
||||
@Directive({selector: '[dir]'})
|
||||
class WithInput {
|
||||
constructor() { dirInstance = this; }
|
||||
@Input() dir: string = '';
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
template: '<ng-template *ngIf="true" i18n-dir dir="Hello {{ name }}"></ng-template>',
|
||||
})
|
||||
class TestComp {
|
||||
name = 'Angular';
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [TestComp, WithInput]});
|
||||
const fixture = TestBed.createComponent(TestComp);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(dirInstance !.dir).toBe('Bonjour Angular');
|
||||
});
|
||||
|
||||
it('should apply i18n attributes during second template pass', () => {
|
||||
loadTranslations({[computeMsgId('Set')]: 'Set'});
|
||||
@Directive({
|
||||
|
Reference in New Issue
Block a user