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';
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()

View File

@ -2932,6 +2932,28 @@ describe('compiler compliance', () => {
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', () => {

View File

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