fix(ivy): don't match directives against attribute bindings (#31541)

Fixes Ivy matching directives against attribute bindings (e.g. `[attr.some-directive]="foo"`). Works by excluding attribute bindings from the attributes array during compilation. This has the added benefit of generating less code.

**Note:** My initial approach to implementing this was to have a different marker for attribute bindings so that they can be ignored when matching directives, however as I was implementing it I realized that the attributes in that array were only used for directive matching (as far as I could tell). I decided to drop the attribute bindings completely, because it results in less generated code.

PR Close #31541
This commit is contained in:
crisbeto
2019-07-13 13:34:34 +02:00
committed by Matias Niemelä
parent 9e83822679
commit 12fd06916b
6 changed files with 70 additions and 9 deletions

View File

@ -202,6 +202,30 @@ describe('directives', () => {
expect(fixture.debugElement.query(By.directive(TestDir))).toBeTruthy();
});
it('should not match directives based on attribute bindings', () => {
const calls: string[] = [];
@Directive({selector: '[dir]'})
class MyDir {
ngOnInit() { calls.push('MyDir.ngOnInit'); }
}
@Component({
selector: `my-comp`,
template: `<p [attr.dir]="direction"></p><p dir="rtl"></p>`,
})
class MyComp {
direction = 'auto';
}
TestBed.configureTestingModule({declarations: [MyDir, MyComp]});
const fixture = TestBed.createComponent(MyComp);
fixture.detectChanges();
// Expect only one directive to be instantiated.
expect(calls).toEqual(['MyDir.ngOnInit']);
});
});
describe('outputs', () => {