網上的文章和教程基本上寫到組件加載完成就沒了!沒了?!而且都是只能存在一個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);}
新聞熱點
疑難解答
圖片精選