在通常的開發中,若是要建立一個模態視圖,基本的思路是建立一個不可見的頂層視圖,而後在須要的時候,展現這個頂層視圖,那麼基本的模態視圖就建立完成了。javascript
在Angluar中,咱們可使用CDK(component dev kit)
中的Overlay
來構建模態視圖,它把模態的構建過程抽象出來,造成了一個可複用的組件。java
首先,簡單的介紹一下CDK:typescript
The Component Dev Kit (CDK) is a set of tools that implement common interaction patterns whilst being unopinionated about their presentation. It represents an abstraction of the core functionalities found in the Angular Material library, without any styling specific to Material Design. Think of the CDK as a blank state of well-tested functionality upon which you can develop your own bespoke components.npm
簡單的翻譯一下,就是:bash
CDK 是一個這樣的工具集,它實現了一系列通用的交互模式,同時不會去影響他們的展現效果。它是 Angluar Material 組件庫中沒有特定於 Material Design 樣式的核心功能的抽象。將CDK視爲通過良好測試的功能的空狀態,您在它上構建本身的定製組件。函數
若是你不使用Angluar Material
來構建你的應用,那麼須要就引入CDK
。工具
npm i @angular/cdk --save
複製代碼
引入完畢後,就能夠開始咱們的空狀態模態框的構建。測試
Overlay
是一個工廠類,它每次調用create
都會建立一個OverlayRef
,而後咱們就使用OverlayRef
來將要展現的內容附在上面(調用attach
)。this
那麼接下來,就要說明一下,overlayRef
建立後如何展現咱們的視圖。首先,咱們經過如下代碼來建立一個簡單的overlayRef
。lua
const overlayRef = this.overlay.create();
複製代碼
建立完畢後,使用overlayRef
的attach
函數來展現視圖。attach
函數接受一個參數,這個參數的類型能夠是 TemplatePortal
或者ComponentPortal
。
那麼,這兩個Portal
的做用是顯而易見,要麼獲取已存在的嵌入視圖(TemplatePortal
),要麼動態建立宿主視圖(ComponentPortal
)。固然,這兩個Portal
的構造過程也不盡相同。
TemplatePortal
:接受兩個參數,第一個參數是模板引用,第二個參數是當前的視圖容器。
ComponentPortal
:接受一個參數,其爲組件構造函數。 很顯然動態建立組件須要在module
或者宿主組件的entryComponents
屬性添加須要的被建立組件。
建立完後,代碼以下:
// Template形式
@ViewChild('someTemplate')
templateRef: TemplateRef;
...
const portal = new TemplatePortal(templateRef, viewContainerRef);
overlayRef.attach(portal);
// component的形式
const portal = new ComponentPortal(YourComponent);
overlayRef.attach(portal);
複製代碼
經過依賴注入的方式,咱們能夠引入Overlay到一個可注入服務或者組件中。這裏,爲了抽象,引入Overlay
到一個可注入服務——ModalService
。
export class ModalService {
constructor(private overlay: Overlay) {}
}
複製代碼
就要構建一個通用的調用方法:
// 這裏要注意,`TemplatePortal`第二個參數在要視圖組件中經過依賴注入才能拿到正確的引用。
// 緣由也很簡單,Angular的`Service`是經過`Injector`來構建的,
// `Injector`會在應用初始化的時候建立,
// 此時`Service`已經生成,而`ViewContainerRef`仍未生成,從而致使依賴錯誤。
// 因此,咱們把`ViewContainerRef`看成參數,而不能看成注入對象。
openTemplate<T>(templateRef: TemplateRef<T>, viewContainerRef: ViewContainerRef) {
const config = new OverlayConfig();
// ...setup your config
const overlayRef = this.overlay.create(config);
const portal = new TemplatePortal(templateRef, viewContainerRef);
overlayRef.attach(portal);
return overlayRef;
}
複製代碼
這樣,一個通用的ModalService
就構建完畢了。
簡單的介紹瞭如何使用Overlay
,以及一個簡單的可複用ModalService
的構建。但願可以對你瞭解整個Overlay
的使用過程有所幫助,下一篇將介紹如何構建可複用的ModalComponent
。