理解Angular2中的ViewContainerRef

而井不想說話發表於2018-12-26

原文連結:netbasal.com/angular-2-u…
作者:Netanel Basal
譯者:而井

理解Angular2中的ViewContainerRef

譯者注:雖然文章標題寫的是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元素的兄弟(節點)被插入。

理解Angular2中的ViewContainerRef

用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元素的兄弟(節點)被插入。

理解Angular2中的ViewContainerRef

你可以將ViewContainerRef用日誌輸出,來檢視它的元素是什麼:

理解Angular2中的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>插入檢視容器的效果。

相關文章