网上的文章和教程基本上写到组件加载完成就没了!没了?!而且都是只能存在一个dialog,想要打开另一个dialog必须先销毁当前打开的dialog,之后看过 material 的实现方式,怪自己太蠢看不懂源码,就只能用自己的方式来实现一个dialog组件了
Dialog组件的目标:可以同时存在多个Dialog,可销毁指定Dialog,销毁后html中无组件残留且提供回调
动态加载组件的实现方式有两种,angular4.0版本之前使用ComponentFactoryResolver来实现,4.0之后可以使用更便捷的ngComponentOutlet来实现,
通过ComponentFactoryResolver实现动态载入
首先理一下ViewChild、ViewChildren、ElementRef、ViewContainerRef、ViewRef、ComponentRef、ComponentFactoryResolver之间的关系:
ViewChild 与 ViewChildren
ViewChild是通过模板引用变量(#)或者指令(directive)用来获取 Angular Dom 抽象类,ViewChild可以使用 ElementRef 或者 ViewContainerRef 进行封装。
@ViewChild('customerRef') customerRef:ElementRef;
ViewChildren通过模板引用变量或者指令用来获取QueryList,像是多个ViewChild组成的数组。
@ViewChildren(ChildDirective) viewChildren: QueryList<ChildDirective>;
ElementRef 与 ViewContainerRef
ViewChild可以使用 ElementRef 或者 ViewContainerRef 进行封装,那么 ElementRef 和 ViewContainerRef 的区别是什么?
用 ElementRef 进行封装,然后通过 .nativeElement 来获取原生Dom元素
console.log(this.customerRef.nativeElement.outerHTML);
ViewContainerRef :视图的容器,包含创建视图的方法和操作视图的api(组件与模板共同定义了视图)。api会返回 ComponentRef 与 ViewRef,那么这两个又是什么?
// 使用ViewContainetRef时,请使用read声明@ViewChild('customerRef',{read: ViewContainerRef}) customerRef:ViewContainerRef;···this.customerRef.createComponent(componentFactory) // componentFactory之后会提到
ViewRef 与 ComponentRef
ViewRef 是最小的UI单元,ViewContainerRef api操作和获取的就是ViewRef
ComponentRef:宿主视图(组件实例视图)通过 ViewContainerRef 创建的对组件视图的引用,可以获取组件的信息并调用组件的方法
ComponentFactoryResolver
要获取 ComponentRef ,需要调用 ViewContainer 的 createComponent 方法,方法需要传入ComponentFactoryResolver创建的参数
constructor( private componentFactoryResolver:ComponentFactoryResolver) { }viewInit(){ componentFactory = this.componentFactoryResolver.resolveComponentFactory(DialogComponent); // 获取对组件视图的引用,到这一步就已经完成了组件的动态加载 componentRef = this.customerRef.createComponent(componentFactory); // 调用载入的组件的方法 componentRef.instance.dialogInit(component);}
新闻热点
疑难解答
图片精选