原文連接: https://netbasal.com/angular-...
做者: Netanel Basal
譯者: 而井
譯者注:雖然文章標題寫的是Angular2,但其實泛指的是Angular2+,讀者能夠將其運用到最新的Angular版本中。
若是你曾經須要用編程的方式來插入新的組件或模版,你可能已經用過了ViewContainerRef
服務了。javascript
在閱讀了(許多)文章和問題後,我發現了許多(人)對於ViewContainerRef
的疑惑,因此讓我試着向你解釋什麼是ViewContainerRef
。html
注意:本文不是關於如何用編程的方式來建立組件的(文章)。(譯者注:只是爲了闡述什麼是ViewContainerRef
)java
讓咱們迴歸到純JavaScript上來開始(教程)。根據下面的標記,你的任務是添加一個新段落來做爲當前(節點)的一個兄弟(節點)。git
<p class=」one」>Element one</p>
爲了簡化(操做),讓咱們使用JQuery:github
$('<p>Element two</p>').insertAfter('.one');
當你須要添加新的DOM元素(即:組件、模版)時,你須要一個能夠插入這個元素的位置。typescript
Angular也沒有什麼黑魔法。它也只是JavaScript。若是你想插入新的組件或模版,你須要告訴Angular,哪裏去放置這個元素。編程
因此ViewContainerRef就是:app
一個你能夠將新的組件做爲其兄弟(節點)的DOM元素(容器)。
(譯者注:即若是你以某個元素或組件做爲視圖容器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元素的兄弟
(節點)被插入。dom
@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
。this
在這個例子中,容器元素就是div
元素,模版將做爲這個div
元素的兄弟(節點)被插入。
你能夠將ViewContainerRef
用日誌輸出,來查看它的元素是什麼:
你能夠在這裏試玩這些代碼。
好了本文到此結束。
雖然做者已經說得很透徹了,可是因爲動態插入組件、模版有不少種排列組合,我(譯者)作了一些樣例代碼來輔助你理解,目前代碼已經上傳到GitHub上了,地址是:https://github.com/RIO-LI/ang...
這個參考項目目前包含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
:用來演示以一個<ng-container>元素爲視圖容器ViewContainerRef,將一個<ng-template>
插入視圖容器的效果。