You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中ViewContainerRef的createEmbeddedView与insert方法差异解析

Angular中ViewContainerRef的createEmbeddedView与insert方法差异解析

核心原因:每个视图实例(ViewRef)只能归属一个容器

这两个方法的本质区别在于是否生成新的视图实例:

  • createEmbeddedView:每次调用都会基于传入的TemplateRef生成一个全新的ViewRef实例,并直接插入当前ViewContainerRef容器。给vc1和vc2分别调用一次,就会生成两个独立的视图,各自挂载到对应容器,最终两个容器都会显示模板内容。

  • insert:它的作用是把已存在的ViewRef实例插入到容器中。但Angular的视图实例有唯一归属限制——一个ViewRef只能被附加在一个容器上。当你把同一个view先插入vc1再插入vc2时,Angular会自动将这个视图从vc1移除,再添加到vc2里,最终只有vc2会显示内容。

重新初始化视图后的逻辑

执行以下代码时:

this.vcr1.insert(view)
view = this.tpl.createEmbeddedView(null) //重新初始化
this.vcr2.insert(view)

第一次插入的是第一个ViewRef实例,之后调用createEmbeddedView生成了第二个全新的ViewRef实例,再插入vc2。此时是两个完全独立的视图实例,分别属于vc1和vc2,所以两个容器都会显示模板内容。

代码示例验证

模板代码:

<ng-container #vc1></ng-container>
<ng-template #tpl>
  <span>I am span in template  </span>
</ng-template>

<ng-container #vc2></ng-container>
<button (click)="addView()">Add new view</button>

组件代码:

import { Component, TemplateRef, ViewChild, ViewContainerRef } from '@angular/core';

export class AppComponent {
    @ViewChild('tpl') tpl!: TemplateRef<any>;
    @ViewChild('vc1', {read: ViewContainerRef}) vcr1!: ViewContainerRef
    @ViewChild('vc2', {read: ViewContainerRef}) vcr2!: ViewContainerRef

    addView(){
        // 情况1:使用createEmbeddedView,生成两个独立视图
        this.vcr1.createEmbeddedView(this.tpl)
        this.vcr2.createEmbeddedView(this.tpl)
        // 输出:I am span in template I am span in template

        // 情况2:使用同一个ViewRef实例插入,最终只有一个容器显示
        // let view = this.tpl.createEmbeddedView(null)
        // this.vcr1.insert(view)
        // this.vcr2.insert(view)
        // 输出:I am span in template 
    }
}

内容的提问来源于stack exchange,提问作者Dinesh Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 22:09:58