【问题标题】:What's the difference between ViewContainerRef's remove() and ComponentRef's destroy()?ViewContainerRef 的 remove() 和 ComponentRef 的 destroy() 有什么区别?
【发布时间】:2020-03-02 11:50:00
【问题描述】:

我知道 ViewContainerRef 的 remove() 会破坏关联的视图,那么定义它的组件是否也被破坏了? ComponentRef 的 destroy() 与 ViewContainerRef 的 remove() 有什么区别,什么时候应该使用其中一个?

例如,这里我动态创建并显示一个子组件。

@ViewChild('taskView', {static: true, read: ViewContainerRef}) vc: ViewContainerRef;

compRef : ComponentRef;

constructor(private CFR: ComponentFactoryResolver){ }

ngOnInit() {
  const factory=this.CFR.resolveComponentFactory(TaskItemComponent);
  const componentRef=this.vc.createComponent(factory);
  this.compRef= componentRef;
}


我意识到我可以通过两种方式删除这个动态添加的组件,或者通过使用 ViewContainerRef 的删除来销毁视图,如下所示:

let vcrIndex: number = this.VCR.indexOf(this.compRef)
this.VCR.remove(vcrIndex);

或者像这样销毁组件实例本身:

this.compRef.destroy();

在我的应用中效果是一样的。然而这两者有什么区别呢?我也对这个早期的堆栈溢出帖子感到困惑: Does ViewContainerRef.clear() remove component from memory?

投票最多的答案写道

No, if you assign parent component property to componentRef angular won't remove component from memory.

Angular only destroys component and removes its own references to this component. But reference to componentRef remains to live in your component property. So i would assign null to it. This way garbage collect will be able to clear memory"

这是否意味着即使在我的 componentRef 上调用了 destroy() 之后,我的 componentRef 仍然指向被破坏的实例?调用 destroy() 或 remove() 时内存中发生了什么?

【问题讨论】:

    标签: angular typescript


    【解决方案1】:

    正如MDN documentation 状态

    垃圾收集算法依赖的主要概念是 参考的概念。 ...为了释放对象的内存,它 需要明确设置为不可访问。

    这意味着如果你有一些引用你的组件的东西,那么它仍然会出现在内存中。

    这是否意味着即使在我的 componentRef 上调用了 destroy() 我的 componentRef 仍然指向被破坏的实例??

    在您销毁保留componentRef 属性的类(或服务)之前,它仍将指向已销毁的实例。如果您销毁组件但您的类(您在其中操作动态组件)将在此之后继续存在,那么最好将 componentRef 属性分配给 null

    至于区别,他们做的事情是一样的:

    ComponentRef.destroy()

    destroy() {
       if (this._appRef) {
         this._appRef.detachView(this);
       } else if (this._viewContainerRef) {
         // does detachEmbeddedView internally
         this._viewContainerRef.detach(this._viewContainerRef.indexOf(this)); 
       }
       Services.destroyView(this._view);
     }
    

    ViewContainerRef.remove

    remove(index?: number): void {
      const viewData = detachEmbeddedView(this._data, index);
      if (viewData) {
        Services.destroyView(viewData);
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 2010-11-09
      • 1970-01-01
      • 2015-09-25
      相关资源
      最近更新 更多