我有一个包含动态创建组件的App组件。
父组件具有<ng-content>
元素,以便我们可以在Parent组件中投影子组件。
应用组件:
@Component({
selector: 'my-app',
template:`<ng-container #parentcontainer></ng-container>`,
})
父组件:
@Component({
selector: 'parent',
template: `
<ng-container #container></ng-container>
<ng-content></ng-content>
`
})
子组件:
@Component({
selector: 'child',
template: `<label>
<input type="radio">
</label>
`
})
我的问题是,有没有办法在Child组件中访问App组件的ViewContainerRef(#parentcontainer)?目标是在稍后阶段动态插入#parentcontainer中的其他组件,就像从子组件点击一些按钮一样。
以下是StackBlitz
上的工作示例答案 0 :(得分:3)
您可以在子组件中创建新组件,并将其附加到DOM中的任何位置
// remember to add YourComponent to entryComponents: [] of the module
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(YourComponent);
let componentRef = viewContainerRef.createComponent(componentFactory, index);
componentRef.instance.model = model; // where model is an input
componentRef.changeDetectorRef.detectChanges(); // update it's view
let htmlElement = (componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
// Now do what you want with the htmlElement e.g. document.querySelector('body').appendChild(htmlElement)
这对你有用吗?请注意,只要子组件处于活动状态,该组件才会保持活动状态
或者,保持组件在应用程序持续时间内保持活动状态,创建服务并在AppComponent级别提供一次。请注意,这使用 ApplicationRef ,它允许您调用 attachView() - 这可能是一个解决方案
constructor(
private componentFactoryResolver: ComponentFactoryResolver,
private appRef: ApplicationRef,
private injector: Injector
) { }
appendComponentToBody(component: any) {
const componentRef = this.componentFactoryResolver
.resolveComponentFactory(component)
.create(this.injector);
this.appRef.attachView(componentRef.hostView);
const domElem = (componentRef.hostView as EmbeddedViewRef<any>)
.rootNodes[0] as HTMLElement;
// Append to body or wherever you want
document.body.appendChild(domElem);
}
有关服务example here
的详细信息最佳解决方案可能是针对 Portal和PortalHost 使用 Angular Material CDK 功能。这是一个非常新的,但它的目的是从一个在实际的my-app元素之外运行的Angular应用程序中创建组件 - 这可能是一个更好的长期解决方案 - 它已被使用在他们的例子中制作模态等