fix(ivy): ignore empty bindings (#28059)

This update aligns Ivy behavior with ViewEngine related to empty bindings (for example <div [someProp]></div>): empty bindings are ignored.

PR Close #28059
This commit is contained in:
Andrew Kushnir 2019-01-10 15:54:48 -08:00
parent 9a128a8068
commit 9260b5e0b4
4 changed files with 51 additions and 21 deletions

View File

@ -120,6 +120,23 @@ describe('compiler compliance: bindings', () => {
const result = compile(files, angularFiles); const result = compile(files, angularFiles);
expectEmit(result.source, template, 'Incorrect interpolated property binding'); expectEmit(result.source, template, 'Incorrect interpolated property binding');
}); });
it('should ignore empty bindings', () => {
const files: MockDirectory = {
app: {
'example.ts': `
import {Component} from '@angular/core';
@Component({
selector: 'test',
template: '<div [someProp]></div>'
})
class FooCmp {}
`
}
};
const result = compile(files, angularFiles);
expect(result.source).not.toContain('i0.ɵelementProperty');
});
}); });
describe('host bindings', () => { describe('host bindings', () => {

View File

@ -908,6 +908,21 @@ describe('ngtsc behavioral tests', () => {
'changeDetection must be a member of ChangeDetectionStrategy enum from @angular/core'); 'changeDetection must be a member of ChangeDetectionStrategy enum from @angular/core');
}); });
it('should ignore empty bindings', () => {
env.tsconfig();
env.write(`test.ts`, `
import {Component} from '@angular/core';
@Component({
selector: 'test',
template: '<div [someProp]></div>'
})
class FooCmp {}
`);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).not.toContain('i0.ɵelementProperty');
});
it('should correctly recognize local symbols', () => { it('should correctly recognize local symbols', () => {
env.tsconfig(); env.tsconfig();
env.write('module.ts', ` env.write('module.ts', `

View File

@ -709,21 +709,20 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
}); });
} }
} else if (instruction) { } else if (instruction) {
const params: any[] = [];
const isAttributeBinding = input.type === BindingType.Attribute;
const sanitizationRef = resolveSanitizationFn(input.securityContext, isAttributeBinding);
if (sanitizationRef) params.push(sanitizationRef);
// TODO(chuckj): runtime: security context
const value = input.value.visit(this._valueConverter); const value = input.value.visit(this._valueConverter);
this.allocateBindingSlots(value); if (value !== undefined) {
const params: any[] = [];
this.updateInstruction(input.sourceSpan, instruction, () => { const isAttributeBinding = input.type === BindingType.Attribute;
return [ const sanitizationRef = resolveSanitizationFn(input.securityContext, isAttributeBinding);
o.literal(elementIndex), o.literal(input.name), if (sanitizationRef) params.push(sanitizationRef);
this.convertPropertyBinding(implicit, value), ...params this.allocateBindingSlots(value);
]; this.updateInstruction(input.sourceSpan, instruction, () => {
}); return [
o.literal(elementIndex), o.literal(input.name),
this.convertPropertyBinding(implicit, value), ...params
];
});
}
} else { } else {
this._unsupported(`binding type ${input.type}`); this._unsupported(`binding type ${input.type}`);
} }

View File

@ -444,14 +444,13 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
})); }));
fixmeIvy('FW-814: Bindings with an empty value should be ignored in the compiler') it('should ignore empty bindings', fakeAsync(() => {
.it('should ignore empty bindings', fakeAsync(() => { const ctx = _bindSimpleProp('[someProp]', TestData);
const ctx = _bindSimpleProp('[someProp]', TestData); ctx.componentInstance.a = 'value';
ctx.componentInstance.a = 'value'; ctx.detectChanges(false);
ctx.detectChanges(false);
expect(renderLog.log).toEqual([]); expect(renderLog.log).toEqual([]);
})); }));
it('should support interpolation', fakeAsync(() => { it('should support interpolation', fakeAsync(() => {
const ctx = _bindSimpleProp('someProp="B{{a}}A"', TestData); const ctx = _bindSimpleProp('someProp="B{{a}}A"', TestData);