angular - 从投影的子组件Angular 5内部获取父ViewContainerRef
问题描述
我有一个带有动态创建组件的 App 组件。父组件有一个<ng-content>
元素,这样我们就可以在父组件中投影我们的子组件。
应用组件:
@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>
`
})
我的问题是,有什么方法可以访问子组件内的 App 组件的 ViewContainerRef (#parentcontainer) 吗?目标是稍后在#parentcontainer 中动态插入其他组件,例如从子组件单击某些按钮。
这是StackBlitz上的工作示例
解决方案
您可以从子组件中创建一个新组件,并将它的 HTML 元素附加到 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);
}
这里有关于服务示例的更多详细信息
最好的解决方案可能是对Portal 和 PortalHost使用Angular Material CDK功能。它很新,但它的目的是从 Angular 应用程序中创建在实际 my-app 元素之外运行的组件 - 这可能是一个更好的长期解决方案 - 它用于在他们的示例中制作模态等
推荐阅读
- asp.net-mvc - Configure MiniCssExtractPlugin
- javascript - django模型按列表过滤
- javascript - 正则表达式:如何拆分句子,然后用 Javascript 中的分隔符重新加入它们?
- tsql - 使用“状态”向客户端指示错误号是否合理?
- command-line-interface - 使用 package.json 中的配置从 CLI 运行 prettier
- go - 使用 golang 将 DSA 密钥解析为 tls 配置对象
- python - 如何在不获取 ValueError 的情况下使用 plotly 库进行绘图?
- javascript - 尝试将 Response 对象读入 arrayBuffer 会导致错误 Failed To Fetch
- android - 在从 Firebase 实时数据库请求更多数据之前清除列表
- javascript - 函数内部声明的 Javascript 连接是否持久?