From 9260b5e0b4320b63d48d9b0bb032e71a748c083b Mon Sep 17 00:00:00 2001 From: Andrew Kushnir Date: Thu, 10 Jan 2019 15:54:48 -0800 Subject: [PATCH] fix(ivy): ignore empty bindings (#28059) This update aligns Ivy behavior with ViewEngine related to empty bindings (for example
): empty bindings are ignored. PR Close #28059 --- .../r3_view_compiler_binding_spec.ts | 17 ++++++++++++ .../compiler-cli/test/ngtsc/ngtsc_spec.ts | 15 +++++++++++ .../compiler/src/render3/view/template.ts | 27 +++++++++---------- .../change_detection_integration_spec.ts | 13 +++++---- 4 files changed, 51 insertions(+), 21 deletions(-) diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_binding_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_binding_spec.ts index e4d5da4bbb..e93e8f9e34 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_binding_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_binding_spec.ts @@ -120,6 +120,23 @@ describe('compiler compliance: bindings', () => { const result = compile(files, angularFiles); 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: '
' + }) + class FooCmp {} + ` + } + }; + const result = compile(files, angularFiles); + expect(result.source).not.toContain('i0.ɵelementProperty'); + }); }); describe('host bindings', () => { diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts index 49bdf8380e..1df79883b7 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -908,6 +908,21 @@ describe('ngtsc behavioral tests', () => { '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: '
' + }) + class FooCmp {} + `); + env.driveMain(); + const jsContents = env.getContents('test.js'); + expect(jsContents).not.toContain('i0.ɵelementProperty'); + }); + it('should correctly recognize local symbols', () => { env.tsconfig(); env.write('module.ts', ` diff --git a/packages/compiler/src/render3/view/template.ts b/packages/compiler/src/render3/view/template.ts index 4ebd220376..ab1d3e94e0 100644 --- a/packages/compiler/src/render3/view/template.ts +++ b/packages/compiler/src/render3/view/template.ts @@ -709,21 +709,20 @@ export class TemplateDefinitionBuilder implements t.Visitor, LocalResolver }); } } 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); - this.allocateBindingSlots(value); - - this.updateInstruction(input.sourceSpan, instruction, () => { - return [ - o.literal(elementIndex), o.literal(input.name), - this.convertPropertyBinding(implicit, value), ...params - ]; - }); + if (value !== undefined) { + const params: any[] = []; + const isAttributeBinding = input.type === BindingType.Attribute; + const sanitizationRef = resolveSanitizationFn(input.securityContext, isAttributeBinding); + if (sanitizationRef) params.push(sanitizationRef); + this.allocateBindingSlots(value); + this.updateInstruction(input.sourceSpan, instruction, () => { + return [ + o.literal(elementIndex), o.literal(input.name), + this.convertPropertyBinding(implicit, value), ...params + ]; + }); + } } else { this._unsupported(`binding type ${input.type}`); } diff --git a/packages/core/test/linker/change_detection_integration_spec.ts b/packages/core/test/linker/change_detection_integration_spec.ts index 139a0fffeb..6b036a4683 100644 --- a/packages/core/test/linker/change_detection_integration_spec.ts +++ b/packages/core/test/linker/change_detection_integration_spec.ts @@ -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(() => { - const ctx = _bindSimpleProp('[someProp]', TestData); - ctx.componentInstance.a = 'value'; - ctx.detectChanges(false); + it('should ignore empty bindings', fakeAsync(() => { + const ctx = _bindSimpleProp('[someProp]', TestData); + ctx.componentInstance.a = 'value'; + ctx.detectChanges(false); - expect(renderLog.log).toEqual([]); - })); + expect(renderLog.log).toEqual([]); + })); it('should support interpolation', fakeAsync(() => { const ctx = _bindSimpleProp('someProp="B{{a}}A"', TestData);