diff --git a/packages/core/src/render3/component_ref.ts b/packages/core/src/render3/component_ref.ts index a2f787db70..c049428499 100644 --- a/packages/core/src/render3/component_ref.ts +++ b/packages/core/src/render3/component_ref.ts @@ -113,7 +113,9 @@ export class ComponentFactory extends viewEngine_ComponentFactory { private componentDef: ComponentDef, private ngModule?: viewEngine_NgModuleRef) { super(); this.componentType = componentDef.type; - this.selector = componentDef.selectors[0][0] as string; + + // default to 'div' in case this component has an attribute selector + this.selector = componentDef.selectors[0][0] as string || 'div'; this.ngContentSelectors = componentDef.ngContentSelectors ? componentDef.ngContentSelectors : []; this.isBoundToModule = !!ngModule; diff --git a/packages/core/test/acceptance/view_container_ref_spec.ts b/packages/core/test/acceptance/view_container_ref_spec.ts index fdf6a8f74b..3eed859422 100644 --- a/packages/core/test/acceptance/view_container_ref_spec.ts +++ b/packages/core/test/acceptance/view_container_ref_spec.ts @@ -114,6 +114,41 @@ describe('ViewContainerRef', () => { expect(testParent.childNodes[1].textContent).toBe('hello'); } }); + + it('should support attribute selectors in dynamically created components', () => { + @Component({selector: '[hello]', template: 'Hello'}) + class HelloComp { + } + + @NgModule({entryComponents: [HelloComp], declarations: [HelloComp]}) + class HelloCompModule { + } + + @Component({ + template: ` + + ` + }) + class TestComp { + @ViewChild('container', {read: ViewContainerRef, static: false}) vcRef !: ViewContainerRef; + + constructor(public cfr: ComponentFactoryResolver) {} + + createComponent() { + const factory = this.cfr.resolveComponentFactory(HelloComp); + this.vcRef.createComponent(factory); + } + } + + TestBed.configureTestingModule({declarations: [TestComp], imports: [HelloCompModule]}); + const fixture = TestBed.createComponent(TestComp); + fixture.detectChanges(); + expect(fixture.debugElement.nativeElement.innerHTML).not.toContain('Hello'); + + fixture.componentInstance.createComponent(); + fixture.detectChanges(); + expect(fixture.debugElement.nativeElement.innerHTML).toContain('Hello'); + }); }); describe('insert', () => {