理解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>插入视图容器的效果。

相关文章
相关标签/搜索