From c12b6fa0282ef6881d602f2d86b38afcf9bb1cd8 Mon Sep 17 00:00:00 2001 From: Andrew Kushnir Date: Thu, 27 Jun 2019 10:56:40 -0700 Subject: [PATCH] fix(ivy): attach host element for views created via TestBed.createComponent (#31318) Prior to this commit, host element of a view created via TestBed.createComponent was not attached to the component's host, making it problematic to use TestBed.createComponent API in component factories, which might be used for testing purposes only. This behavior is observed in google3 app tests and was supported by VE, so this commit aligns Ivy and VE. PR Close #31318 --- packages/core/src/render3/component_ref.ts | 5 +-- .../acceptance/view_container_ref_spec.ts | 32 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/packages/core/src/render3/component_ref.ts b/packages/core/src/render3/component_ref.ts index f6fe2d964d..7f3a321288 100644 --- a/packages/core/src/render3/component_ref.ts +++ b/packages/core/src/render3/component_ref.ts @@ -214,8 +214,9 @@ export class ComponentFactory extends viewEngine_ComponentFactory { this.componentType, component, createElementRef(viewEngine_ElementRef, tElementNode, rootLView), rootLView, tElementNode); - if (isInternalRootView) { - // The host element of the internal root view is attached to the component's host view node + if (isInternalRootView || isIsolated) { + // The host element of the internal or isolated root view is attached to the component's host + // view node. componentRef.hostView._tViewNode !.child = tElementNode; } return componentRef; diff --git a/packages/core/test/acceptance/view_container_ref_spec.ts b/packages/core/test/acceptance/view_container_ref_spec.ts index b9de42aa3d..186be8a9e4 100644 --- a/packages/core/test/acceptance/view_container_ref_spec.ts +++ b/packages/core/test/acceptance/view_container_ref_spec.ts @@ -1086,6 +1086,38 @@ describe('ViewContainerRef', () => { expect((element.namespaceURI || '').toLowerCase()).not.toContain('svg'); }); + it('should be compatible with componentRef generated via TestBed.createComponent in component factory', + () => { + @Component({ + selector: 'child', + template: `Child Component`, + }) + class Child { + } + + @Component({ + selector: 'comp', + template: '', + }) + class Comp { + @ViewChild('ref', {read: ViewContainerRef, static: true}) + viewContainerRef?: ViewContainerRef; + + ngOnInit() { + const makeComponentFactory = (componentType: any) => ({ + create: () => TestBed.createComponent(componentType).componentRef, + }); + this.viewContainerRef !.createComponent(makeComponentFactory(Child) as any); + } + } + + TestBed.configureTestingModule({declarations: [Comp, Child]}); + + const fixture = TestBed.createComponent(Comp); + fixture.detectChanges(); + + expect(fixture.debugElement.nativeElement.innerHTML).toContain('Child Component'); + }); }); describe('insertion points and declaration points', () => {