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:
parent
ea2d453118
commit
b51d8dd438
|
@ -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()
|
||||||
|
|
|
@ -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', () => {
|
||||||
|
|
|
@ -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)]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue