本文將探討material2中popup彈窗即其Dialog模塊的實現。
使用方法
深入源碼
進入material2的源碼,先從 MatDialog 的代碼入手,找到這個 open 方法:
open<T>( componentOrTemplateRef: ComponentType<T> | TemplateRef<T>, config?: MatDialogConfig): MatDialogRef<T> { // 防止重復打開 const inProgressDialog = this.openDialogs.find(dialog => dialog._isAnimating()); if (inProgressDialog) { return inProgressDialog; } // 組合配置 config = _applyConfigDefaults(config); // 防止id沖突 if (config.id && this.getDialogById(config.id)) { throw Error(`Dialog with id "${config.id}" exists already. The dialog id must be unique.`); } // 第一步:創建彈出層 const overlayRef = this._createOverlay(config); // 第二步:在彈出層上添加彈窗容器 const dialogContainer = this._attachDialogContainer(overlayRef, config); // 第三步:把傳入的組件添加到創建的彈出層中創建的彈窗容器中 const dialogRef = this._attachDialogContent(componentOrTemplateRef, dialogContainer, overlayRef, config); // 首次彈窗要添加鍵盤監聽 if (!this.openDialogs.length) { document.addEventListener('keydown', this._boundKeydown); } // 添加進隊列 this.openDialogs.push(dialogRef); // 默認添加一個關閉的訂閱 關閉時要移除此彈窗 // 當是最后一個彈窗時觸發全部關閉的訂閱并移除鍵盤監聽 dialogRef.afterClosed().subscribe(() => this._removeOpenDialog(dialogRef)); // 觸發打開的訂閱 this.afterOpen.next(dialogRef); return dialogRef;}總體看來彈窗的發起分為三部曲:
彈出層的創建
對于其他組件,僅僅封裝模板以及內部實現就足夠了,最多還要增加與父組件的數據、事件交互,所有這些事情,單使用angular Component就足夠實現了,在何處使用就將組件選擇器放到哪里去完事。
但對于彈窗組件,事先并不知道會在何處使用,因此不適合實現為一個組件后通過選擇器安放到頁面的某處,而應該將其作為彈窗插座放置到全局,并通過服務來調用。
material2也要面臨這個問題,這個彈窗插座是避免不了的,那就在內部實現它,在實際調用彈窗方法時動態創建這個插座就可以了。要實現效果是:對用戶來說只是在單純調用一個 open 方法,由material2內部來創建一個彈出層,并在這個彈出層上創建彈窗。
找到彈出層的創建代碼如下:
新聞熱點
疑難解答
圖片精選