共计 2396 个字符,预计需要花费 6 分钟才能阅读完成。
原文链接:https://netbasal.com/angular-… 作者:Netanel Basal 译者:而井
译者注:虽然文章标题写的是 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 元素的兄弟(节点)被插入。
用 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 元素的兄弟(节点)被插入。
你可以将 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> 插入视图容器的效果。