原文連結:netbasal.com/angular-2-u…
作者:Netanel Basal
譯者:而井
譯者注:雖然文章標題寫的是Angular2,但其實泛指的是Angular2+,讀者可以將其運用到最新的Angular版本中。
如果你曾經需要用程式設計的方式來插入新的元件或模版,你可能已經用過了ViewContainerRef
服務了。
在閱讀了(許多)文章和問題後,我發現了許多(人)對於ViewContainerRef
的疑惑,所以讓我試著向你解釋什麼是ViewContainerRef
。
注意:本文不是關於如何用程式設計的方式來建立元件的(文章)。(譯者注:只是為了闡述什麼是ViewContainerRef
)
讓我們迴歸到純JavaScript上來開始(教程)。根據下面的標記,你的任務是新增一個新段落來作為當前(節點)的一個兄弟(節點)。
<p class=”one”>Element one</p>
複製程式碼
為了簡化(操作),讓我們使用JQuery:
$('<p>Element two</p>').insertAfter('.one');
複製程式碼
當你需要新增新的DOM元素(即:元件、模版)時,你需要一個可以插入這個元素的位置。
Angular也沒有什麼黑魔法。它也只是JavaScript。如果你想插入新的元件或模版,你需要告訴Angular,哪裡去放置這個元素。
所以ViewContainerRef就是:
一個你可以將新的元件作為其兄弟(節點)的DOM元素(容器)。 (譯者注:即如果你以某個元素或元件作為檢視容器ViewContainerRef,對其新增的元件、模版,將成為這個檢視容器的兄弟節點)
用依賴注入來獲取ViewContainerRef
@Component({
selector: 'vcr',
template: `
<template #tpl>
<h1>ViewContainerRef</h1>
</template>
`,
})
export class VcrComponent {
@ViewChild('tpl') tpl;
constructor(private _vcr: ViewContainerRef) {
}
ngAfterViewInit() {
this._vcr.createEmbeddedView(this.tpl);
}
}
@Component({
selector: 'my-app',
template: `
<vcr></vcr>
`,
})
export class App {
}
複製程式碼
我們在這個元件中注入了服務。在這個樣例中,容器將指向你的宿主
元素(vcr 元素),並且模版將作為vcr元素的兄弟
(節點)被插入。
用ViewChild來獲取ViewContainerRef
@Component({
selector: 'vcr',
template: `
<template #tpl>
<h1>ViewContainerRef</h1>
</template>
<div>Some element</div>
<div #container></div>
`,
})
export class VcrComponent {
@ViewChild('container', { read: ViewContainerRef }) _vcr;
@ViewChild('tpl') tpl;
ngAfterViewInit() {
this._vcr.createEmbeddedView(this.tpl);
}
}
@Component({
selector: 'my-app',
template: `
<div>
<vcr></vcr>
</div>
`,
})
export class App {
}
複製程式碼
我們可以使用ViewChild
裝飾器來收集任何我們檢視上的元素,並將其當作ViewContainerRef
。
在這個例子中,容器元素就是div
元素,模版將作為這個div
元素的兄弟(節點)被插入。
你可以將ViewContainerRef
用日誌輸出,來檢視它的元素是什麼:
你可以在這裡試玩這些程式碼。 好了本文到此結束。
譯者附
雖然作者已經說得很透徹了,但是由於動態插入元件、模版有很多種排列組合,我(譯者)做了一些樣例程式碼來輔助你理解,目前程式碼已經上傳到GitHub上了,地址是:github.com/RIO-LI/angu… 這個參考專案目前包含6的目錄,每一個都是單獨的Angular專案,每一個目錄具體演示內容如下:
component-insert-into-component-viewcontainer
: 用來演示以元件作為檢視容器ViewContainerRef,將另外一個元件插入檢視容器的效果。
component-insert-into-dom-viewcontainer
: 用來演示以DOM元素為檢視容器ViewContainerRef,將一個元件插入檢視容器的效果。
component-insert-into-self-viewcontainer
: 用來演示以元件自身作為檢視容器ViewContainerRef,將元件中的模版插入檢視容器的效果。
ngtemplate-insert-into-component-viewcontainer
: 用來演示以一個元件作為檢視容器ViewContainerRef,將一個<ng-template>
插入檢視容器的效果。
ngtemplate-insert-into-dom-viewcontainer
: 用來演示以一個DOM元素為檢視容器ViewContainerRef,將一個<ng-template>
插入檢視容器的效果。
ngtemplate-insert-into-ngcontainer-viewcontainer
:用來演示以一個元素為檢視容器ViewContainerRef,將一個<ng-template>
插入檢視容器的效果。