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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43680712/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 04:29:38  来源:igfitidea点击:

Does ViewContainerRef.clear() remove component from memory?

angulartypescriptangular-components

提问by Leonid Bor

When I create a component using ViewContainerRefand assign instance to a property of parent component, which is responsible for child component creation, do I need to set this property to nullafter I call ViewContainerRef.clear()if I want memory to be freed?

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

回答by yurzui

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

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

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 nullto it. This way garbage collect will be able to clear memory

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

Plunker Example(add => clear => check)

Plunker 示例(添加 => 清除 => 检查)

@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);
  }
}

See also

也可以看看

回答by Julia Passynkova

I am not 100% sure but Angular calls ngOnDestroy() method of dynamically created components when their parent component is removed by Router.

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

here is a plunker: https://plnkr.co/edit/rAX6745xZi6EvP8N78IL?p=preview

这是一个plunker: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 {}