fix(ivy): error for empty bindings on ng-template (#30829)

Fixes Ivy throwing an error if it runs into an empty property binding on an `ng-template` (e.g. `<ng-template [something]=""></ng-template>`) by not generating an update instruction for it.

Fixes #30801.
This PR resoves FW-1356.

PR Close #30829
This commit is contained in:
crisbeto 2019-06-04 22:03:32 +02:00 committed by Misko Hevery
parent ea2d453118
commit b51d8dd438
3 changed files with 43 additions and 4 deletions

View File

@ -204,6 +204,20 @@ describe('NgTemplateOutlet', () => {
fixture.componentInstance.value = 'baz'; fixture.componentInstance.value = 'baz';
detectChangesAndExpectText(''); detectChangesAndExpectText('');
}); });
// https://github.com/angular/angular/issues/30801
it('should not throw if the context is left blank', () => {
const template = `
<ng-template #testTemplate>test</ng-template>
<ng-template [ngTemplateOutlet]="testTemplate" [ngTemplateOutletContext]=""></ng-template>
`;
expect(() => {
fixture = createTestComponent(template);
detectChangesAndExpectText('test');
}).not.toThrow();
});
}); });
@Injectable() @Injectable()

View File

@ -2932,6 +2932,28 @@ describe('compiler compliance', () => {
expectEmit(source, SomeDirectiveDefinition, 'Incorrect SomeDirective.ngDirectiveDef'); expectEmit(source, SomeDirectiveDefinition, 'Incorrect SomeDirective.ngDirectiveDef');
}); });
it('should not throw for empty property bindings on ng-template', () => {
const files = {
app: {
'example.ts': `
import {Component, NgModule} from '@angular/core';
@Component({
selector: 'my-app',
template: '<ng-template [id]=""></ng-template>'
})
export class MyComponent {
}
@NgModule({declarations: [MyComponent]})
export class MyModule {}`
}
};
expect(() => compile(files, angularFiles)).not.toThrow();
});
}); });
describe('inherited base classes', () => { describe('inherited base classes', () => {

View File

@ -1024,11 +1024,14 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
attrs.forEach(input => { attrs.forEach(input => {
if (input instanceof t.BoundAttribute) { if (input instanceof t.BoundAttribute) {
const value = input.value.visit(this._valueConverter); const value = input.value.visit(this._valueConverter);
if (value !== undefined) {
this.allocateBindingSlots(value); this.allocateBindingSlots(value);
this.updateInstruction( this.updateInstruction(
templateIndex, template.sourceSpan, R3.property, templateIndex, template.sourceSpan, R3.property,
() => [o.literal(input.name), this.convertPropertyBinding(context, value, true)]); () => [o.literal(input.name), this.convertPropertyBinding(context, value, true)]);
} }
}
}); });
} }