fix(ivy): support attribute selectors in dynamic component creation (#31812)

This commit fixes a bug where we assumed all dynamically created
components would have tag-name selectors, so we passed through the
"tag name" to the renderer as the first index of the selector. For
components with attribute selectors, the tag name would be "", so
the renderer would try to create an element with tag name "" and
throw. Now we default to a "div" element the same way that View
Engine did.

Closes #31785

PR Close #31812
This commit is contained in:
Kara Erickson 2019-07-23 16:10:01 -07:00 committed by Misko Hevery
parent b6aeaceb8e
commit b696413a79
2 changed files with 38 additions and 1 deletions

View File

@ -113,7 +113,9 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
private componentDef: ComponentDef<any>, private ngModule?: viewEngine_NgModuleRef<any>) {
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;

View File

@ -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: `
<ng-container #container></ng-container>
`
})
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', () => {