fix(ivy): move views that are already attached in insert() (#29047)
Currently if a user accidentally calls ViewContainerRef.insert() with a view that has already been attached, we do not clean up the references properly, so we create a view tree with a cycle. This causes an infinite loop when the view is destroyed. This PR ensures that we fall back to ViewContainerRef.move() behavior if we try to insert a view that is already attached. This fixes the cycle and honors the user intention. PR Close #29047
This commit is contained in:

committed by
Andrew Kushnir

parent
ff8e4dddb2
commit
7ac58bec8a
@ -13,7 +13,7 @@ import {ComponentDef, DirectiveDef} from '../interfaces/definition';
|
||||
import {TNode, TNodeFlags} from '../interfaces/node';
|
||||
import {RNode} from '../interfaces/renderer';
|
||||
import {StylingContext} from '../interfaces/styling';
|
||||
import {FLAGS, HEADER_OFFSET, HOST, LView, LViewFlags, TData, TVIEW} from '../interfaces/view';
|
||||
import {FLAGS, HEADER_OFFSET, HOST, LView, LViewFlags, PARENT, TData, TVIEW} from '../interfaces/view';
|
||||
|
||||
|
||||
|
||||
@ -182,3 +182,18 @@ export function readPatchedLView(target: any): LView|null {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a boolean for whether the view is attached to the change detection tree.
|
||||
*
|
||||
* Note: This determines whether a view should be checked, not whether it's inserted
|
||||
* into a container. For that, you'll want `viewAttachedToContainer` below.
|
||||
*/
|
||||
export function viewAttachedToChangeDetector(view: LView): boolean {
|
||||
return (view[FLAGS] & LViewFlags.Attached) === LViewFlags.Attached;
|
||||
}
|
||||
|
||||
/** Returns a boolean for whether the view is attached to a container. */
|
||||
export function viewAttachedToContainer(view: LView): boolean {
|
||||
return isLContainer(view[PARENT]);
|
||||
}
|
||||
|
Reference in New Issue
Block a user