如果你曾经需要用编程的方式来插入新的组件或模版,你可能已经用过了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用日志输出,来查看它的元素是什么:
|