真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

如何使用AngularCDKPortal創(chuàng)建動(dòng)態(tài)內(nèi)容

這篇文章將為大家詳細(xì)講解有關(guān)如何使用Angular CDK Portal創(chuàng)建動(dòng)態(tài)內(nèi)容,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

專注于為中小企業(yè)提供成都做網(wǎng)站、網(wǎng)站制作服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)綦江免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上千多家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

Angular 官方提供了一套組件開發(fā)套件 Component Dev Kit (CDK),作為各種 Angular 組件開發(fā)的基礎(chǔ)工具,其中就提供 “Portal(傳送門)” 來輔助動(dòng)態(tài)視圖的創(chuàng)建。

這個(gè) ”動(dòng)態(tài)視圖“ 可以是組件、TemplateRef 或者 DOM 元素,分別對(duì)應(yīng)三種 Portal 類型(ComponentPortal、TemplatePortal、DomPortal)。它們?nèi)齻€(gè)的抽象泛型基類是 Portal,有三個(gè)方法:attach(掛載到容器)、detach(從容器移除)、isAttached(判斷視圖是否是掛載狀態(tài))。

而容器也是由一個(gè)抽象類 BasePortalOutlet 定義,和視圖類似,包含 attach(給容器掛載視圖)、detach(從容器移除視圖)、dispose(銷毀容器)、isAttached(是否有掛載視圖)。它的主要實(shí)現(xiàn)是 DomPortalOutlet 類。用以掛載三種類型的動(dòng)態(tài)視圖。

創(chuàng)建動(dòng)態(tài)內(nèi)容

先來看看三種動(dòng)態(tài)視圖的創(chuàng)建。

ComponentPortal

相比原生 API,要?jiǎng)?chuàng)建一個(gè)動(dòng)態(tài)組件非常的簡(jiǎn)單,只需要把組件類傳入 ComponentPortal 構(gòu)造函數(shù)即可。

this.componentPortal = new ComponentPortal(ExampleComponent);

可以傳入任意自定義的組件類,用以創(chuàng)建 ComponentPortal 對(duì)象,再動(dòng)態(tài)插入視圖中。

?注意:Angular 9 后的版本推薦使用 Ivy 編譯器,如果是老版本編譯器,傳入的組件類,需要在 Module 的 entryComponents 中聲明,并且這個(gè) Module 不能懶加載。

TemplatePortal

TemplatePortal 的構(gòu)建,相比組件,多了一個(gè)參數(shù)(ViewContainerRef)??催^前一篇應(yīng)該對(duì)它非常熟悉了,需要依賴它調(diào)用 createEmbeddedView() 來創(chuàng)建嵌入視圖。這里通過構(gòu)造注入,直接使用當(dāng)前組件的 ViewContainerRef 實(shí)例。


  

一些需要?jiǎng)討B(tài)插入的內(nèi)容.

@ViewChild('testTemplate') templatePortalContent: TemplateRef;

constructor(private _viewContainerRef: ViewContainerRef) { }

ngAfterViewInit() {
  this.templatePortal = new TemplatePortal(
    this.templatePortalContent,
    this._viewContainerRef
  );
}

除了通過構(gòu)造函數(shù),TemplatePortal 也有一個(gè)指令(CdkPortal)可以便捷創(chuàng)建。


  

一些需要?jiǎng)討B(tài)插入的內(nèi)容.

  一些需要?jiǎng)討B(tài)插入的內(nèi)容.

然后通過 @ViewChild 就可以獲得 TemplatePortal 的實(shí)例了。

DomPortal

就像上面的示例通過 @ViewChild 獲取 Template 實(shí)例來創(chuàng)建,類似的也可以獲取 ElementRef 來創(chuàng)建動(dòng)態(tài)的 DOM。

原生DOM內(nèi)容
@ViewChild('domPortalContent') domPortalContent: ElementRef;
ngAfterViewInit() {
  this.domPortal = new DomPortal(this.domPortalContent);
}

可以動(dòng)態(tài)的將這段 DOM 轉(zhuǎn)移到任意位置。要注意的是,轉(zhuǎn)移之后,原來的數(shù)據(jù)綁定,或者綁定的指令可能不會(huì)再繼續(xù)更新。

插入容器

前面三種類型的 Portal 都說了可以渲染到任意位置,那具體怎么渲染呢?

CdkPortOutlet

最簡(jiǎn)單的就是通過 CdkPortOutlet 指令了:

  

anyPortal 傳值上面三個(gè)中任意的 Portal 實(shí)例,都會(huì)動(dòng)態(tài)渲染到當(dāng)前位置。

和原生 API 的指令不同,它可以自動(dòng)判斷是什么類型的 Portal。另外,它還有個(gè)額外的事件:attached,通過這個(gè)事件,可以獲取到掛載的組件實(shí)例,或者 TemplateRef。這也讓和掛載組件的交互變得十分方便了。

構(gòu)造容器實(shí)例

不過既然說了是可以渲染到任意位置,那自然也包括 Angular 應(yīng)用外部,要渲染到應(yīng)用之外,就需要咱們通過構(gòu)造函數(shù)創(chuàng)建容器實(shí)例。

這個(gè)容器類就是 DomPortalOutlet,它是 PortalOutlet 的實(shí)現(xiàn)子類。它的構(gòu)造參數(shù)主要是:Element(掛載視圖的DOM節(jié)點(diǎn))、ComponentFactoryResolver(和上篇一樣,用以動(dòng)態(tài)構(gòu)建組件)、appRef(當(dāng)前 Angular 應(yīng)用的整體實(shí)例)、Injector(注入器,用于傳遞依賴)。

constructor(
  private viewContainerRef: ViewContainerRef,
  @Inject(DOCUMENT) private document: any,
  private injector: Injector,
  private componentFactoryResolver: ComponentFactoryResolver
) {
  // 在下創(chuàng)建外部宿主元素
  const container = this.document.createElement('div');
  container.classList.add('outside-portal-container');
  this.outsideContainer = this.document.body.appendChild(container);
  // 獲取應(yīng)用實(shí)例
  this.appRef = this.injector.get(ApplicationRef);
  // 創(chuàng)建外部容器
  this.outsideOutlet = new DomPortalOutlet(
    this.outsideContainer, 
    this.componentFactoryResolver, 
    this.appRef, 
    this.injector
  );
}

// 在應(yīng)用外部插入動(dòng)態(tài)組件。
openComponentPortalOutSideAngularContext(): void {
  const componentPortal = new ComponentPortal(AlertComponent);
  const componentRef = this.outsideOutlet.attach(componentPortal);
    componentRef.instance.closeAlert.subscribe(() => {
      this.outsideOutlet.detach();
    });
}

// 在應(yīng)用外部插入動(dòng)態(tài)模板。
openTemplatePortalInsideAngularContext(): void {
  const templatePortal = new TemplatePortal(this.templatePortalContent, this.viewContainerRef);
  this.outsideOutlet.attach(templatePortal);
}

除了掛載視圖到應(yīng)用外的 DOM 元素中,還需要能夠跟視圖進(jìn)行數(shù)據(jù)交互,組件可以通過注入依賴,模板可以傳入上下文對(duì)象。

const injectionToken = new InjectionToken('Sharing data with outside component portal');
const customInjector = Injector.create({ providers: [{ provide: CustomInjectionToken, useValue: 'test value' }] });

對(duì)創(chuàng)建 outsideContainer 的代碼稍作修改,把這個(gè) customInjector 作為參數(shù)傳入(而不是使用當(dāng)前組件的 injector)

// 重點(diǎn)是第四個(gè)參數(shù)
new DomPortalOutlet(this.outsideContainer, this.componentFactoryResolver, this.appRef, customInjector);

相應(yīng)的,這個(gè)組件只需要按這個(gè) injectionToken 注入依賴即可:

constructor(@Inject(injectionToken) public customData: any) {}

給模板傳遞上下文就比較簡(jiǎn)單了,在創(chuàng)建 TemplatePortal 對(duì)象時(shí),傳入上下文對(duì)象即可:

// 重點(diǎn)是第三個(gè)參數(shù)
new TemplatePortal(this.templatePortalContent, this.viewContainerRef, { customData:'test values' });

關(guān)于“如何使用Angular CDK Portal創(chuàng)建動(dòng)態(tài)內(nèi)容”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。


新聞標(biāo)題:如何使用AngularCDKPortal創(chuàng)建動(dòng)態(tài)內(nèi)容
網(wǎng)站鏈接:http://weahome.cn/article/psggcc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部