ViewContainerRef.clear() 是不是从内存中删除组件?

Posted

技术标签:

【中文标题】ViewContainerRef.clear() 是不是从内存中删除组件?【英文标题】:Does ViewContainerRef.clear() remove component from memory?ViewContainerRef.clear() 是否从内存中删除组件? 【发布时间】:2017-09-26 14:27:19 【问题描述】:

当我使用ViewContainerRef 创建一个组件并将实例分配给父组件的一个属性时,该属性负责创建子组件,如果我愿意,我是否需要在调用ViewContainerRef.clear() 后将此属性设置为null内存要释放?

【问题讨论】:

【参考方案1】:

不,如果您将父组件属性分配给componentRef,角度不会从内存中删除组件。

Angular 只销毁组件并删除它自己对该组件的引用。但是对 componentRef 的引用仍然存在于您的组件属性中。所以我会给它分配null。这样垃圾收集就可以清理内存了

Plunker Example(添加 => 清除 => 检查)

@Component(
  selector: 'my-app',
  template: `
    <div>
      <button (click)="addComponent()">Add component</button>
      <div #container></div>
      <button (click)="clear()">Clear</button>
      <button (click)="check()">check</button>
    </div>
  `,
)
export class App 
  comp: ComponentRef<DynamicComponent>;

  constructor(
     private vcRef: ViewContainerRef, 
     private resolver: ComponentFactoryResolver) 

  addComponent() 
    let factory = this.resolver.resolveComponentFactory(DynamicComponent);
    this.comp = this.vcRef.createComponent(factory);
  

  clear() 
    this.vcRef.clear();
  

  check() 
    alert(this.comp);
  

另见

https://developer.mozilla.org/en/docs/Web/javascript/Memory_Management#Garbage_collection

【讨论】:

【参考方案2】:

我不是 100% 确定,但是当路由删除父组件时,Angular 会调用动态创建的组件的 ngOnDestroy() 方法。

这里有一个笨蛋:https://plnkr.co/edit/rAX6745xZi6EvP8N78IL?p=preview

import Component, NgModule,Injector, ComponentFactoryResolver, 
TemplateRef, ViewChild, ViewContainerRef from '@angular/core'
import BrowserModule from '@angular/platform-browser'
import Routes, RouterModule, Route from '@angular/router';

@Component(
  selector: 'my-other',
  template: `<div>other</div>`
)
export class Other 

@Component(
  selector: 'my-cmp',
  template: `<div>
     my cmp 
     <ng-content></ng-content>
   </div>
   `
)
export class MyComp 
  ngOnDestroy() 
    console.log('dynamic component ngOnDestroy is called');
  


@Component(
  selector: 'my-app',
  template: `
     <a routerLink="/viewchild">go viewchild</a>
     <a routerLink="/other">go other</a>
     <div>
     <router-outlet></router-outlet>
     </div>
     `
)
 export class App     

@Component(
  selector: 'my-prt',
  template: `
    <div>
      <button (click)="create()">Create</button>

       <div #vc>
          <my-cmp>static one</my-cmp>
       </div>
    </div>
  `,
)
export class Parent 
  @ViewChild('vc', read: ViewContainerRef) vc: ViewContainerRef;
  cmpRef = [];

  constructor(private injector: Injector, private componentFactoryResolver: ComponentFactoryResolver) 
  

  create() 
    const projectableNodes = [[document.createTextNode('a'), document.createTextNode('b')]];
    const factory = this.componentFactoryResolver.resolveComponentFactory(MyComp);
    this.cmpRef.push(this.vc.createComponent(factory, this.injector, undefined, projectableNodes);
  

  ngOnDestroy() 
     //this.cmpRef.forEach(ref=>ref=null);
  


let routes = [
  path:'viewchild', component: Parent,
  path:'other', component: Other
];

@NgModule(
  imports: [ BrowserModule, RouterModule.forRoot(routes ],
  declarations: [ App, MyComp, Parent, Other ],
  entryComponents: [MyComp],
  bootstrap: [ App ]
)
export class AppModule 

【讨论】:

以上是关于ViewContainerRef.clear() 是不是从内存中删除组件?的主要内容,如果未能解决你的问题,请参考以下文章