Angluar-模態視圖構建簡析(A)

在通常的開發中,若是要建立一個模態視圖,基本的思路是建立一個不可見的頂層視圖,而後在須要的時候,展現這個頂層視圖,那麼基本的模態視圖就建立完成了。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

Overlay是一個工廠類,它每次調用create都會建立一個OverlayRef,而後咱們就使用OverlayRef來將要展現的內容附在上面(調用attach)。this

那麼接下來,就要說明一下,overlayRef建立後如何展現咱們的視圖。首先,咱們經過如下代碼來建立一個簡單的overlayReflua

const overlayRef = this.overlay.create();
複製代碼

建立完畢後,使用overlayRefattach函數來展現視圖。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到一個可注入服務或者組件中。這裏,爲了抽象,引入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

相關文章
相關標籤/搜索