国产gaysexchina男同gay,japanrcep老熟妇乱子伦视频,吃奶呻吟打开双腿做受动态图,成人色网站,国产av一区二区三区最新精品

Angular9動(dòng)態(tài)組件

2020-07-01 14:47 更新

&本節(jié)講的是一個(gè)用于顯示廣告的范例,而部分廣告攔截器插件,比如 Chrome 的 AdGuard,可能會(huì)破壞其工作邏輯,因此,請(qǐng)?jiān)诒卷?yè)關(guān)閉那些插件。

組件的模板不會(huì)永遠(yuǎn)是固定的。應(yīng)用可能會(huì)需要在運(yùn)行期間加載一些新的組件。

動(dòng)態(tài)組件加載

下面的例子展示了如何構(gòu)建動(dòng)態(tài)廣告條。

英雄管理局正在計(jì)劃一個(gè)廣告活動(dòng),要在廣告條中顯示一系列不同的廣告。幾個(gè)不同的小組可能會(huì)頻繁加入新的廣告組件。 再用只支持靜態(tài)組件結(jié)構(gòu)的模板顯然是不現(xiàn)實(shí)的。

你需要一種新的組件加載方式,它不需要在廣告條組件的模板中引用固定的組件。

Angular 自帶的 API 就能支持動(dòng)態(tài)加載組件。

指令

在添加組件之前,先要定義一個(gè)錨點(diǎn)來(lái)告訴 Angular 要把組件插入到什么地方。

廣告條使用一個(gè)名叫 AdDirective 的輔助指令來(lái)在模板中標(biāo)記出有效的插入點(diǎn)。

Path:"src/app/ad.directive.ts" 。

import { Directive, ViewContainerRef } from '@angular/core';


@Directive({
  selector: '[ad-host]',
})
export class AdDirective {
  constructor(public viewContainerRef: ViewContainerRef) { }
}

AdDirective 注入了 ViewContainerRef 來(lái)獲取對(duì)容器視圖的訪問(wèn)權(quán),這個(gè)容器就是那些動(dòng)態(tài)加入的組件的宿主。

@Directive 裝飾器中,要注意選擇器的名稱(chēng):ad-host,它就是你將應(yīng)用到元素上的指令。

加載組件

廣告條的大部分實(shí)現(xiàn)代碼都在 "ad-banner.component.ts" 中。 為了讓這個(gè)例子簡(jiǎn)單點(diǎn),HTML 被直接放在了 @Component 裝飾器的 template 屬性中。

<ng-template> 元素就是剛才制作的指令將應(yīng)用到的地方。 要應(yīng)用 AdDirective,回憶一下來(lái)自 "ad.directive.ts" 的選擇器 ad-host。把它應(yīng)用到 <ng-template>(不用帶方括號(hào))。 這下,Angular 就知道該把組件動(dòng)態(tài)加載到哪里了。

Path:"src/app/ad-banner.component.ts (template)" 。

template: `
            <div class="ad-banner-example">
              <h3>Advertisements</h3>
              <ng-template ad-host></ng-template>
            </div>
          `

<ng-template> 元素是動(dòng)態(tài)加載組件的最佳選擇,因?yàn)樗粫?huì)渲染任何額外的輸出。

解析組件

深入看看 "ad-banner.component.ts" 中的方法。

AdBannerComponent 接收一個(gè) AdItem 對(duì)象的數(shù)組作為輸入,它最終來(lái)自 AdService。 AdItem 對(duì)象指定要加載的組件類(lèi),以及綁定到該組件上的任意數(shù)據(jù)。 AdService 可以返回廣告活動(dòng)中的那些廣告。

AdBannerComponent 傳入一個(gè)組件數(shù)組可以在模板中放入一個(gè)廣告的動(dòng)態(tài)列表,而不用寫(xiě)死在模板中。

通過(guò) getAds() 方法,AdBannerComponent 可以循環(huán)遍歷 AdItems 的數(shù)組,并且每三秒調(diào)用一次 loadComponent() 來(lái)加載新組件。

Path:"src/app/ad-banner.component.ts (excerpt)" 。

export class AdBannerComponent implements OnInit, OnDestroy {
  @Input() ads: AdItem[];
  currentAdIndex = -1;
  @ViewChild(AdDirective, {static: true}) adHost: AdDirective;
  interval: any;


  constructor(private componentFactoryResolver: ComponentFactoryResolver) { }


  ngOnInit() {
    this.loadComponent();
    this.getAds();
  }


  ngOnDestroy() {
    clearInterval(this.interval);
  }


  loadComponent() {
    this.currentAdIndex = (this.currentAdIndex + 1) % this.ads.length;
    const adItem = this.ads[this.currentAdIndex];


    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(adItem.component);


    const viewContainerRef = this.adHost.viewContainerRef;
    viewContainerRef.clear();


    const componentRef = viewContainerRef.createComponent(componentFactory);
    (<AdComponent>componentRef.instance).data = adItem.data;
  }


  getAds() {
    this.interval = setInterval(() => {
      this.loadComponent();
    }, 3000);
  }
}

這里的 loadComponent() 方法很重要。 來(lái)一步步看看。首先,它選取了一個(gè)廣告。

&loadComponent() 如何選擇廣告

&loadComponent() 方法使用某種算法選擇了一個(gè)廣告。

&(譯注:循環(huán)選取算法)首先,它把 currentAdIndex 遞增一,然后用它除以 AdItem 數(shù)組長(zhǎng)度的余數(shù)作為新的 currentAdIndex 的值, 最后用這個(gè)值來(lái)從數(shù)組中選取一個(gè) adItem。

loadComponent() 選取了一個(gè)廣告之后,它使用 ComponentFactoryResolver 來(lái)為每個(gè)具體的組件解析出一個(gè) ComponentFactory。 然后 ComponentFactory 會(huì)為每一個(gè)組件創(chuàng)建一個(gè)實(shí)例。

接下來(lái),你要把 viewContainerRef 指向這個(gè)組件的現(xiàn)有實(shí)例。但你怎么才能找到這個(gè)實(shí)例呢? 很簡(jiǎn)單,因?yàn)樗赶蛄?adHost,而這個(gè) adHost 就是你以前設(shè)置過(guò)的指令,用來(lái)告訴 Angular 該把動(dòng)態(tài)組件插入到什么位置。

回憶一下,AdDirective 曾在它的構(gòu)造函數(shù)中注入了一個(gè) ViewContainerRef。 因此這個(gè)指令可以訪問(wèn)到這個(gè)你打算用作動(dòng)態(tài)組件宿主的元素。

要把這個(gè)組件添加到模板中,你可以調(diào)用 ViewContainerRefcreateComponent()。

createComponent() 方法返回一個(gè)引用,指向這個(gè)剛剛加載的組件。 使用這個(gè)引用就可以與該組件進(jìn)行交互,比如設(shè)置它的屬性或調(diào)用它的方法。

對(duì)選擇器的引用

通常,Angular 編譯器會(huì)為模板中所引用的每個(gè)組件都生成一個(gè) ComponentFactory 類(lèi)。 但是,對(duì)于動(dòng)態(tài)加載的組件,模板中不會(huì)出現(xiàn)對(duì)它們的選擇器的引用。

要想確保編譯器照常生成工廠類(lèi),就要把這些動(dòng)態(tài)加載的組件添加到 NgModuleentryComponents 數(shù)組中:

Path:"src/app/app.module.ts (entry components)" 。

entryComponents: [ HeroJobAdComponent, HeroProfileComponent ],

公共的 AdComponent 接口

在廣告條中,所有組件都實(shí)現(xiàn)了一個(gè)公共接口 AdComponent,它定義了一個(gè)標(biāo)準(zhǔn)化的 API,來(lái)把數(shù)據(jù)傳給組件。

下面就是兩個(gè)范例組件及其 AdComponent 接口:

  1. Path:"src/app/hero-job-ad.component.ts" 。

    import { Component, Input } from '@angular/core';


    import { AdComponent }      from './ad.component';


    @Component({
      template: `
        <div class="job-ad">
          <h4>{{data.headline}}</h4>


          {{data.body}}
        </div>
      `
    })
    export class HeroJobAdComponent implements AdComponent {
      @Input() data: any;


    }

  1. Path:"hero-profile.component.ts" 。

    import { Component, Input }  from '@angular/core';


    import { AdComponent }       from './ad.component';


    @Component({
      template: `
        <div class="hero-profile">
          <h3>Featured Hero Profile</h3>
          <h4>{{data.name}}</h4>


          <p>{{data.bio}}</p>


          <strong>Hire this hero today!</strong>
        </div>
      `
    })
    export class HeroProfileComponent implements AdComponent {
      @Input() data: any;
    }

  1. Path:"ad.component.ts" 。

    export interface AdComponent {
      data: any;
    }

結(jié)果展示

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)