fix(ivy): do not throw if host style is on a template node (#30498)

In View Engine, we would simply ignore host style bindings on template nodes. In Ivy,
we are throwing a "Cannot read length of undefined" error instead. For backwards
compatibility, we should also ignore these bindings rather than blowing up.

PR Close #30498
This commit is contained in:
Kara Erickson 2019-05-15 18:22:50 -07:00 committed by Jason Aden
parent f2ae452f01
commit c62c5e2999
2 changed files with 26 additions and 3 deletions

View File

@ -35,9 +35,12 @@ export function registerHostDirective(context: StylingContext, directiveIndex: n
*/
export function enqueueHostInstruction<T extends Function>(
context: StylingContext, priority: number, instructionFn: T, instructionFnArgs: ParamsOf<T>) {
const buffer: HostInstructionsQueue = context[StylingIndex.HostInstructionsQueue] !;
const index = findNextInsertionIndex(buffer, priority);
buffer.splice(index, 0, priority, instructionFn, instructionFnArgs);
const buffer: HostInstructionsQueue|null = context[StylingIndex.HostInstructionsQueue];
// Buffer may be null if host element is a template node. In this case, just ignore the style.
if (buffer != null) {
const index = findNextInsertionIndex(buffer, priority);
buffer.splice(index, 0, priority, instructionFn, instructionFnArgs);
}
}
/**

View File

@ -160,4 +160,24 @@ describe('styling', () => {
tNode: 3,
});
});
it('should not throw if host style binding is on a template node', () => {
// This ex is a bit contrived. In real apps, you might have a shared class that is extended both
// by components with host elements and by directives on template nodes. In that case, the host
// styles for the template directives should just be ignored.
@Directive({selector: 'ng-template[styleDir]', host: {'[style.display]': 'display'}})
class StyleDir {
display = 'block';
}
@Component({selector: 'app-comp', template: `<ng-template styleDir></ng-template>`})
class MyApp {
}
TestBed.configureTestingModule({declarations: [MyApp, StyleDir]});
expect(() => {
const fixture = TestBed.createComponent(MyApp);
fixture.detectChanges();
}).not.toThrow();
});
});