动态组件
如果说,之前在模板中调用的组件是静态组件(比如:app-xxx)
那么不用在模板里声明,而是通过ts动态插入到dom中的组件,可以视为动态组件。
- 动态组件创建模式
创建工厂
创建组件实例
将组件添加到视图树
将组件添加到模板
做其他的监听事件
export class ShowDataComponent implements OnInit {
private container : AlertComponent
private componentRef : ComponentRef <AlertComponent>
constructor(
private cfr : ComponentFactoryResolver,
private inject : Injector,
private appRef : ApplicationRef
){}
private getContainer() : AlertComponent {
//创建指定类型的组件工厂(生产指定类型的组件)
const factory = this.cfr.resolveComponentFactory<AlertComponent>(AlertComponent)
//根据指定类型,创建组件的实例
this.componentRef = factory.create(this.inject)
//将组件视图添加到视图树中,以激活变更检测
this.appRef.attachView(this.componentRef.hostView)
//将组件插入到模板(包括app-alert标签),添加到body最后
document.body.appendChild((this.componentRef.hostView as EmbeddedViewRef<{}>).rootNodes[0] as HTMLElement)
//用location的方式也可以插入dom元素
//document.body.appendChild(this.componentRef.location.nativeElement)
//监听组件销毁事件
this.componentRef.onDestory(()=>{
console.log('componentRef destory')
})
//获取组件实例,相当于用@ViewChild获取子组件一样
const {instance} = this.componentRef
//监听组件到output事件
instance.closed.subscribe(()=>{
this.componentRef.destory();
this.container = null
})
return instance
}
}
entryComponents
要想确保编译器照常生成工厂类,就要把动态组件添加到NgModule的entryCompoonents数组中。
ng9和ng10,动态组件都不需要entryComponents了,当然写了也不没有问题,从v11开始,entryComponents可能被删除。
但在ng8以前,动态组件一定要声明entryComponents
entryComponents:[AlertComponent]
网友评论