美文网首页让前端飞
理解Angular2中的ViewContainerRef

理解Angular2中的ViewContainerRef

作者: 吃不了辣椒 | 来源:发表于2019-03-16 18:06 被阅读0次

    原文链接:https://netbasal.com/angular-2-understanding-viewcontainerref-acc183f3b682
    作者:Netanel Basal
    译者:而井

    image

    译者注:虽然文章标题写的是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元素的兄弟(节点)被插入。

    image

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

    image

    你可以将ViewContainerRef用日志输出,来查看它的元素是什么:

    image

    你可以在这里试玩这些代码。
    好了本文到此结束。

    译者附

    虽然作者已经说得很透彻了,但是由于动态插入组件、模版有很多种排列组合,我(译者)做了一些样例代码来辅助你理解,目前代码已经上传到GitHub上了,地址是:https://github.com/RIO-LI/angular-viewContainerRef-learning
    这个参考项目目前包含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>插入视图容器的效果。

    相关文章

      网友评论

        本文标题:理解Angular2中的ViewContainerRef

        本文链接:https://www.haomeiwen.com/subject/sowsmqtx.html