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

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

【问题讨论】:

    标签: angular typescript angular-components


    【解决方案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);
      }
    }
    

    另见

    【讨论】:

      【解决方案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 {}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-24
        • 1970-01-01
        • 2014-03-25
        • 2014-05-22
        • 2015-09-26
        相关资源
        最近更新 更多