手把手教你使用Angular CDK Portal創建動態內容_第1頁
手把手教你使用Angular CDK Portal創建動態內容_第2頁
手把手教你使用Angular CDK Portal創建動態內容_第3頁
手把手教你使用Angular CDK Portal創建動態內容_第4頁
手把手教你使用Angular CDK Portal創建動態內容_第5頁
已閱讀5頁,還剩2頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第手把手教你使用AngularCDKPortal創建動態內容之前介紹過原生API的動態視圖插入,功能上已經可以滿足大多數使用場景。不過也有一些缺憾,還沒有解決在Angular應用外插入內容的需求,指令也不能跟動態插入的組件有輸入輸出的交互。

好在Angular官方提供了一套組件開發套件ComponentDevKit(CDK),作為各種Angular組件開發的基礎工具,其中就提供Portal(傳送門)來輔助動態視圖的創建。

這個動態視圖可以是組件、TemplateRef或者DOM元素,分別對應三種Portal類型(ComponentPortal、TemplatePortal、DomPortal)。它們三個的抽象泛型基類是PortalT,有三個方法:attach(掛載到容器)、detach(從容器移除)、isAttached(判斷視圖是否是掛載狀態)。

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

創建動態內容

先來看看三種動態視圖的創建。

ComponentPortal

相比原生API,要創建一個動態組件非常的簡單,只需要把組件類傳入ComponentPortal構造函數即可。

ponentPortal=newComponentPortal(ExampleComponent);

可以傳入任意自定義的組件類,用以創建ComponentPortal對象,再動態插入視圖中。

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

TemplatePortal

TemplatePortal的構建,相比組件,多了一個參數(ViewContAInerRef)。看過前一篇應該對它非常熟悉了,需要依賴它調用createEmbeddedView()來創建嵌入視圖。這里通過構造注入,直接使用當前組件的ViewContainerRef實例。

ng-template#testTemplate

p一些需要動態插入的內容./p

/ng-template

@ViewChild(testTemplate)templatePortalContent:TemplateRefany

constructor(private_viewContainerRef:ViewContainerRef){}

ngAfterViewInit(){

this.templatePortal=newTemplatePortal(

this.templatePortalContent,

this._viewContainerRef

}

除了通過構造函數,TemplatePortal也有一個指令(CdkPortal)可以便捷創建。

ng-templatecdkPortal

p一些需要動態插入的內容./p

/ng-template

!--或寫作--

!--和上面寫法是一致的效果--

p*cdkPortal

一些需要動態插入的內容.

/p

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

DomPortal

就像上面的示例通過@ViewChild獲取Template實例來創建,類似的也可以獲取ElementRef來創建動態的DOM。

div#domPortalContentspan原生DOM內容/span/div

@ViewChild(domPortalContent)domPortalContent:ElementRefHTMLElement

ngAfterViewInit(){

this.domPortal=newDomPortal(this.domPortalContent);

}

可以動態的將這段DOM轉移到任意位置。要注意的是,轉移之后,原來的數據綁定,或者綁定的指令可能不會再繼續更新。

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

CdkPortOutlet

最簡單的就是通過CdkPortOutlet指令了:

div

ng-template[cdkPortalOutlet]=anyPortal/ng-template

/div

給anyPortal傳值上面三個中任意的Portal實例,都會動態渲染到當前位置。

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

構造容器實例

不過既然說了是可以渲染到任意位置,那自然也包括Angular應用外部,要渲染到應用之外,就需要咱們通過構造函數創建容器實例。

這個容器類就是DomPortalOutlet,它是PortalOutlet的實現子類。它的構造參數主要是:Element(掛載視圖的DOM節點)、ComponentFactoryResolver(和上篇一樣,用以動態構建組件)、appRef(當前Angular應用的整體實例)、Injector(注入器,用于傳遞依賴)。

constructor(

privateviewContainerRef:ViewContainerRef,

@Inject(DOCUMENT)privatedocument:any,

privateinjector:Injector,

privatecomponentFactoryResolver:ComponentFactoryResolver

//在body下創建外部宿主元素

constcontainer=this.document.createElement(div

container.classList.add(outside-portal-container

this.outsideContainer=this.document.body.appendChild(container);

//獲取應用實例

this.appRef=this.injector.get(ApplicationRef);

//創建外部容器

this.outsideOutlet=newDomPortalOutlet(

this.outsideContainer,

ponentFactoryResolver,

this.appRef,

this.injector

//在應用外部插入動態組件。

openComponentPortalOutSideAngularContext():void{

constcomponentPortal=newComponentPortal(AlertComponent);

constcomponentRef=this.outsideOutlet.attach(componentPortal);

componentRef.instance.closeAlert.subscribe(()={

this.outsideOutlet.detach();

//在應用外部插入動態模板。

openTemplatePortalInsideAngularContext():void{

consttemplatePortal=newTemplatePortal(this.templatePortalContent,this.viewContainerRef);

this.outsideOutlet.attach(templatePortal);

}

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

constinjectionToken=newInjectionTokenany(Sharingdatawithoutsidecomponentportal

constcustomInjector=Injector.create({providers:[{provide:CustomInjectionToken,useValue:testvalue}]});

對創建outsideContainer的代碼稍作修改,把這個customInjector作為參數傳入(而不是使用當前組件的injector)

//重點是第四個參數

newDomPortalOutlet(this.outsideContainer,ponentFactoryResolver,this.appRef,customInjector);

相應的,這個組件只需要按這個injectionToken注入依賴即可:

constructor(@Inject(injectionToken)pu

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論