理解Angular2中的ViewContainerRef

原文連接: https://netbasal.com/angular-...
做者: Netanel Basal
譯者: 而井

圖片描述

譯者注:雖然文章標題寫的是Angular2,但其實泛指的是Angular2+,讀者能夠將其運用到最新的Angular版本中。

若是你曾經須要用編程的方式來插入新的組件或模版,你可能已經用過了ViewContainerRef服務了。javascript

在閱讀了(許多)文章和問題後,我發現了許多(人)對於ViewContainerRef的疑惑,因此讓我試着向你解釋什麼是ViewContainerRefhtml

注意:本文不是關於如何用編程的方式來建立組件的(文章)。(譯者注:只是爲了闡述什麼是ViewContainerRefjava

讓咱們迴歸到純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,對其新增的組件、模版,將成爲這個視圖容器的兄弟節點)

用依賴注入來獲取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

圖片描述

用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裝飾器來收集任何咱們視圖上的元素,並將其看成ViewContainerRefthis

在這個例子中,容器元素就是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>插入視圖容器的效果。

相關文章
相關標籤/搜索