Does ViewContainerRef.clear() remove component from memory?

拟墨画扇 提交于 2020-05-26 04:04:42

问题


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


回答1:


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

Plunker Example (add => clear => check)

@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

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



回答2:


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

here is a 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 {}


来源:https://stackoverflow.com/questions/43680712/does-viewcontainerref-clear-remove-component-from-memory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!