1. 程式人生 > >angular2中動態元件載入

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】