angular2中動態元件載入
參考:angular2(4) 中動態建立元件的兩種方案
參考:DEVELOPING A TABS COMPONENT IN ANGULAR
參考:Create a dynamic tab component with Angular
元件的模板不會永遠是固定的。應用可能會需要在執行期間載入一些新的元件。
這篇部落格為你展示如何使用ComponentFactoryResolver來動態新增元件。
場景:
一天,蔬菜罐頭公司要招聘一位蘿蔔去做蘿蔔乾,因為上個蘿蔔被榨乾了。於是在各大招聘網站上釋出招聘資訊。
崗位:蔬菜罐頭加工人員
需要人數:1
崗位職責:選個秋高氣爽好日子,把脆嫩汁液很充足的蘿蔔洗白白後,用不油膩的菜刀把蘿蔔乾縱切成3釐米到5釐米之間的長條塊,涼上一天。然後找一個適當容量的玻璃罈子,瓦罈子或是瓦缸也行,洗乾淨晾乾。然後採用浸泡法去醃製脆口的蘿蔔乾。
##1.首先找招聘網站把招聘資訊釋出出去(定義一個指令)
動態載入元件,就像蔬菜罐頭公司的崗位等待蘿蔔入坑一樣。蘿蔔怎麼知道該公司有崗位呢?通過招聘網站(指令,就像錨點一樣告訴蘿蔔我司有坑,來吧)。
//定義指令 import { Directive, ViewContainerRef } from '@angular/core'; @Directive({ selector: '[ad-host]', }) export class AdDirective { constructor(public viewContainerRef: ViewContainerRef) { } }
AdDirective注入了ViewContainerRef來獲取對容器檢視的訪問權,這個容器就是那些動態加入的元件的宿主。可以在該容器上建立、插入、刪除元件等等。
在@Directive裝飾器中,要注意選擇器的名稱:ad-host,它就是我們將應用到(容器)元素上的指令
搞個崗位出來(不然蘿蔔來了沒有坑,尬聊嗎,弄個容器出來)
import { Component, Input, AfterViewInit, ViewChild, ComponentFactoryResolver, OnDestroy } from '@angular/core'; import { AdDirective } from './ad.directive'; import { AdItem } from './ad-item'; import { AdComponent } from './ad.component'; @Component({ selector: 'add-banner', template: ` <div class="ad-banner"> <h3>Advertisements</h3> <ng-template ad-host></ng-template> </div> ` }) export class AdBannerComponent implements AfterViewInit, OnDestroy { @Input() ads: AdItem[]; currentAddIndex: number = -1; @ViewChild(AdDirective) adHost: AdDirective; subscription: any; interval: any; constructor(private _componentFactoryResolver: ComponentFactoryResolver) { } ngAfterViewInit() { this.loadComponent(); this.getAds(); } ngOnDestroy() { clearInterval(this.interval); } loadComponent() { this.currentAddIndex = (this.currentAddIndex + 1) % this.ads.length; let adItem = this.ads[this.currentAddIndex]; let componentFactory = this._componentFactoryResolver.resolveComponentFactory(adItem.component); let viewContainerRef = this.adHost.viewContainerRef; viewContainerRef.clear(); let componentRef = viewContainerRef.createComponent(componentFactory); (<AdComponent>componentRef.instance).data = adItem.data; } getAds() { this.interval = setInterval(() => { this.loadComponent(); }, 3000); } }
這個崗位一看就不簡單。要學習的東西很多。比如浸泡法。可以說是一個神坑,包羅永珍。什麼
ngAfterViewInit
,ViewChild
,ComponentFactoryResolver
,OnDestroy
,<ng-template ad-host></ng-template>
等等etc
ViewChild
一個屬性裝飾器,用來從模板檢視中獲取對應的元素,可以通過模板變數獲取,獲取時可以通過 read 屬性設定查詢的條件,就是說可以把此檢視轉為不同的例項ComponentFactoryResolver
一個服務,動態載入元件的核心,這個服務可以將一個元件例項呈現到另一個元件檢視上<ng-template ad-host></ng-template>
來自ad.directive.ts的選擇器ad-host。把它應用到<ng-template>
。 這下,Angular就知道該把元件動態載入到哪裡了ngAfterViewInit
見生命週期鉤子章節OnDestroy
見生命週期鉤子章節
一個簡單的思路便連貫了:特定區域就是一個檢視容器,可以通過 ViewChild 來實現獲取和查詢,然後使用ComponentFactoryResolve將已宣告未例項化的元件解析成為可以動態載入的 component,再將此component 呈現到此前的檢視容器中
【微信公眾號:qdgithub】