【发布时间】:2017-09-26 14:27:19
【问题描述】:
当我使用ViewContainerRef 创建一个组件并将实例分配给父组件的一个属性时,该属性负责创建子组件,如果我愿意,我是否需要在调用ViewContainerRef.clear() 后将此属性设置为null内存要释放?
【问题讨论】:
标签: angular typescript angular-components
当我使用ViewContainerRef 创建一个组件并将实例分配给父组件的一个属性时,该属性负责创建子组件,如果我愿意,我是否需要在调用ViewContainerRef.clear() 后将此属性设置为null内存要释放?
【问题讨论】:
标签: angular typescript angular-components
不,如果您将父组件属性分配给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);
}
}
另见
【讨论】:
我不是 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 {}
【讨论】: