詳解Angular 4.x NgTemplateOutlet
該指令用于基于已有的 TemplateRef
對(duì)象,插入對(duì)應(yīng)的內(nèi)嵌視圖。在應(yīng)用 NgTemplateOutlet 指令時(shí),我們可以通過(guò) [ngTemplateOutletContext]
屬性來(lái)設(shè)置 EmbeddedViewRef
的上下文對(duì)象。綁定的上下文應(yīng)該是一個(gè)對(duì)象,此外可通過(guò) let
語(yǔ)法來(lái)聲明綁定上下文對(duì)象屬性名。
友情提示:若 let 語(yǔ)法未綁定任何屬性名,則上下文對(duì)象中 $implicit 屬性,對(duì)應(yīng)的值將作為默認(rèn)值。
NgTemplateOutlet 指令語(yǔ)法
<ng-container *ngTemplateOutlet="templateRefExp; context: contextExp"></ng-container>
NgTemplateOutlet 使用示例
@Component({ selector: 'ng-template-outlet-example', template: ` <ng-container *ngTemplateOutlet="greet"></ng-container> <hr> <ng-container *ngTemplateOutlet="eng; context: myContext"></ng-container> <hr> <ng-container *ngTemplateOutlet="svk; context: myContext"></ng-container> <hr> <ng-template #greet><span>Hello</span></ng-template> <ng-template #eng let-name><span>Hello {{name}}!</span></ng-template> <ng-template #svk let-person="localSk"><span>Ahoj {{person}}!</span></ng-template> ` }) class NgTemplateOutletExample { myContext = {$implicit: 'World', localSk: 'Svet'}; }
基礎(chǔ)知識(shí)
TemplateRef
TemplateRef 實(shí)例用于表示模板對(duì)象。
ViewContainerRef
ViewContainerRef 實(shí)例提供了 createEmbeddedView()
方法,該方法接收 TemplateRef
對(duì)象作為參數(shù),并將模板中的內(nèi)容作為容器 (comment 元素) 的兄弟元素,插入到頁(yè)面中。
<ng-template>
<ng-template> 用于定義模板,使用 *
語(yǔ)法糖的結(jié)構(gòu)指令,最終都會(huì)轉(zhuǎn)換為 <ng-template>
模板指令,模板內(nèi)的內(nèi)容如果不進(jìn)行處理,是不會(huì)在頁(yè)面中顯示。
<ng-container>
<ng-container> 是一個(gè)邏輯容器,可用于對(duì)節(jié)點(diǎn)進(jìn)行分組,但不作為 DOM 樹(shù)中的節(jié)點(diǎn),它將被渲染為 HTML中的 comment 元素,它可用于避免添加額外的元素來(lái)使用結(jié)構(gòu)指令。
若想進(jìn)一步了解 <ng-template> 與 <ng-container> 的區(qū)別,請(qǐng)參考Angular 4.x 動(dòng)態(tài)創(chuàng)建組件 文章中我有話說(shuō)版塊。
NgTemplateOutlet 源碼分析
NgTemplateOutlet 指令定義
@Directive({ selector: '[ngTemplateOutlet]' })
NgTemplateOutlet 類私有屬性及構(gòu)造函數(shù)
export class NgTemplateOutlet implements OnChanges { // 表示創(chuàng)建的內(nèi)嵌視圖 private _viewRef: EmbeddedViewRef<any>; // 注入ViewContainerRef實(shí)例 constructor(private _viewContainerRef: ViewContainerRef) {} }
NgTemplateOutlet 類輸入屬性
@Input() public ngTemplateOutletContext: Object; // 用于設(shè)定EmbeddedViewRef上下文 @Input() public ngTemplateOutlet: TemplateRef<any>; // 用于設(shè)定TemplateRef對(duì)象
NgTemplateOutlet 指令聲明周期
export class NgTemplateOutlet implements OnChanges { ngOnChanges(changes: SimpleChanges) { // 若this._viewRef已存在,則先從視圖容器中對(duì)應(yīng)的位置移除該視圖。 if (this._viewRef) { this._viewContainerRef.remove(this._viewContainerRef.indexOf(this._viewRef)); } // 若this.ngTemplateOutlet輸入屬性有綁定TemplateRef對(duì)象,則基于設(shè)定的上下文對(duì)象創(chuàng)建內(nèi)嵌視圖 if (this.ngTemplateOutlet) { this._viewRef = this._viewContainerRef.createEmbeddedView( this.ngTemplateOutlet, this.ngTemplateOutletContext); } } }
ngTemplateOutlet
指令的源碼相對(duì)比較簡(jiǎn)單,如果讀者有興趣了解 createEmbeddedView()
方法的內(nèi)部實(shí)現(xiàn),可以參考 Angular 4.x NgIf 文章中的相關(guān)內(nèi)容。
另外需要注意的是使用 let
語(yǔ)法創(chuàng)建模板局部變量,若未設(shè)置綁定的值,則默認(rèn)是上下文對(duì)象中 $implicit
屬性對(duì)應(yīng)的值。為什么屬性名是 $implicit
呢?因?yàn)?Angular 不知道用戶會(huì)如何命名,所以定義了一個(gè)默認(rèn)的屬性名。 即 let-name="$implicit"
與 let-name
是等價(jià)的。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Angular2開(kāi)發(fā)環(huán)境搭建教程之VS Code
不久前WebStorm的頻繁卡死終于讓我受不鳥(niǎo)了,我決定換個(gè)輕量級(jí)的編輯器,嘗試了Emacs、Sublime text,最后選擇了vscode。下面這篇文章主要給大家介紹了關(guān)于Angular2開(kāi)發(fā)環(huán)境搭建教程之VS Code的相關(guān)資料,需要的朋友可以參考下。2017-12-123個(gè)可以改善用戶體驗(yàn)的AngularJS指令介紹
這篇文章主要介紹了3個(gè)可以改善用戶體驗(yàn)的AngularJS指令,AngularJS是一款具有很高人氣的JavaScript框架,需要的朋友可以參考下2015-06-06Agularjs妙用雙向數(shù)據(jù)綁定實(shí)現(xiàn)手風(fēng)琴效果
最近在工作總遇到需要實(shí)現(xiàn)類似手風(fēng)琴效果的需求,下面小編通過(guò)本文給大家分享angularjs巧用雙向數(shù)據(jù)綁定實(shí)現(xiàn)手風(fēng)琴效果,需要的朋友可以參考下2017-05-05AngularJS中的路由使用及實(shí)現(xiàn)代碼
本篇文章主要介紹了AngularJS中的路由使用及實(shí)現(xiàn)代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10深入解析AngularJS框架中$scope的作用與生命周期
這篇文章主要介紹了AngularJS中$scope的作用與生命周期,包括在DOM中添加controller對(duì)象的相關(guān)用法,需要的朋友可以參考下2016-03-03