fix(ivy): ignore non-property bindings to inputs in template type checker (#33130)

Prior to this change, the template type checker would incorrectly bind
non-property bindings such as `[class.strong]`, `[style.color]` and
`[attr.enabled]` to directive inputs of the same name. This is
undesirable, as those bindings are never actually bound to the inputs at
runtime.

Fixes #32099
Fixes #32496
Resolves FW-1596

PR Close #33130
This commit is contained in:
JoostK 2019-10-13 14:39:02 +02:00 committed by Matias Niemelä
parent 6c3c030f0d
commit 08cb2fa80f
2 changed files with 21 additions and 0 deletions

View File

@ -857,6 +857,11 @@ function tcbGetDirectiveInputs(
* a matching binding. * a matching binding.
*/ */
function processAttribute(attr: TmplAstBoundAttribute | TmplAstTextAttribute): void { function processAttribute(attr: TmplAstBoundAttribute | TmplAstTextAttribute): void {
// Skip non-property bindings.
if (attr instanceof TmplAstBoundAttribute && attr.type !== BindingType.Property) {
return;
}
// Skip the attribute if the directive does not have an input for it. // Skip the attribute if the directive does not have an input for it.
if (!propMatch.has(attr.name)) { if (!propMatch.has(attr.name)) {
return; return;

View File

@ -129,6 +129,22 @@ describe('type check blocks', () => {
expect(block).not.toContain('.style = '); expect(block).not.toContain('.style = ');
}); });
it('should only apply property bindings to directives', () => {
const TEMPLATE = `
<div dir [style.color]="'blue'" [class.strong]="false" [attr.enabled]="true"></div>
`;
const DIRECTIVES: TestDeclaration[] = [{
type: 'directive',
name: 'Dir',
selector: '[dir]',
inputs: {'color': 'color', 'strong': 'strong', 'enabled': 'enabled'},
}];
const block = tcb(TEMPLATE, DIRECTIVES);
expect(block).toContain(
'var _t2 = Dir.ngTypeCtor({ color: (null as any), strong: (null as any), enabled: (null as any) });');
expect(block).toContain('"blue"; false; true;');
});
it('should generate a circular directive reference correctly', () => { it('should generate a circular directive reference correctly', () => {
const TEMPLATE = ` const TEMPLATE = `
<div dir #d="dir" [input]="d"></div> <div dir #d="dir" [input]="d"></div>