angular - Vad är skillnaden mellan ViewContainerRefs remove() och ComponentRefs destroy()?
Jag vet att ViewContainerRefs remove() förstör en associerad vy, så blir komponenten som definierade den också förstörd? Vad är skillnaden mellan ComponentRefs destroy() och ViewContainerRefs remove(), och när bör jag använda den ena framför den andra?
Till exempel, här skapar och visar jag dynamiskt en underordnad komponent.
@ViewChild('taskView', {static: true, read: ViewContainerRef}) vc: ViewContainerRef;
compRef : ComponentRef;
constructor(private CFR: ComponentFactoryResolver){ }
ngOnInit() {
const factory=this.CFR.resolveComponentFactory(TaskItemComponent);
const componentRef=this.vc.createComponent(factory);
this.compRef= componentRef;
}
Och jag insåg att jag kunde ta bort denna dynamiskt tillagda komponent på två sätt, antingen genom att förstöra vyn med ViewContainerRefs remove, på följande sätt:
let vcrIndex: number = this.VCR.indexOf(this.compRef)
this.VCR.remove(vcrIndex);
Eller genom att förstöra komponentinstansen själv så här:
this.compRef.destroy();
Effekten i min applikation är densamma. Men vad är skillnaden mellan de två? Jag är också förvirrad av detta tidigare stack overflow-inlägg: Tar ViewContainerRef.clear() bort komponenten från minnet?
Det mest omröstade svaret skrev att
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"
Betyder detta då att även efter att ha kallat destroy() på min componentRef pekar min componentRef fortfarande på den förstörda instansen?? Vad händer i minnet när destroy() eller remove() kallas?
Svar #1
Som MDN-dokumentationen anger
Huvudkonceptet som algoritmer för skräpinsamling bygger på är konceptet referens. ...För att frigöra minnet för ett objekt måste det göras uttryckligen otillgängligt.
Detta betyder att om du har något som refererar till din komponent så kommer det fortfarande att finnas i minnet.
Betyder det här att även efter att ha kallat destroy() på min componentRef så pekar min componentRef fortfarande på den förstörda instansen??
Det kommer fortfarande att peka på den förstörda instansen tills du förstör klassen (eller tjänsten) som håller componentRef-egenskapen. Om du förstör komponenten men din klass (där du manipulerar den dynamiska komponenten) kommer att leva vidare efter det, skulle det vara bättre att tilldela componentRef-egenskapen till null.
När det gäller skillnaden, gör de samma saker:
ComponentRef.destroy()
destroy() {
if (this._appRef) {
this._appRef.detachView(this);
} else if (this._viewContainerRef) {
// does detachEmbeddedView internally
this._viewContainerRef.detach(this._viewContainerRef.indexOf(this));
}
Services.destroyView(this._view);
}
ViewContainerRef.remove
remove(index?: number): void {
const viewData = detachEmbeddedView(this._data, index);
if (viewData) {
Services.destroyView(viewData);
}
}
