fix(core): Refresh transplanted views at insertion point only (#35968)
Only refresh transplanted views at the insertion location in Ivy. Previously, Ivy would check transplanted views at both the insertion and declaration points. This is achieved by adding a marker to the insertion tree when we encounter a transplanted view that needs to be refreshed at its declaration. We use this marker as an extra indication that we still need to descend and refresh those transplanted views at their insertion locations even if the insertion view and/or its parents are not dirty. This change fixes several issues: * Transplanted views refreshed twice if both insertion and declaration are dirty. This could be an error if the insertion component changes result in data not being available to the transplanted view because it is slated to be removed. * CheckAlways transplanted views not refreshed if shielded by non-dirty OnPush (fixes #35400) * Transplanted views still refreshed when insertion tree is detached (fixes #21324) PR Close #35968
This commit is contained in:

committed by
Andrew Kushnir

parent
e5f459d32b
commit
c8c2272a9f
@ -13,7 +13,7 @@ import {LContext, MONKEY_PATCH_KEY_NAME} from '../interfaces/context';
|
||||
import {TConstants, TNode} from '../interfaces/node';
|
||||
import {isProceduralRenderer, RNode} from '../interfaces/renderer';
|
||||
import {isLContainer, isLView} from '../interfaces/type_checks';
|
||||
import {FLAGS, HEADER_OFFSET, HOST, LView, LViewFlags, PARENT, PREORDER_HOOK_FLAGS, RENDERER, TData, TView} from '../interfaces/view';
|
||||
import {FLAGS, HEADER_OFFSET, HOST, LView, LViewFlags, PARENT, PREORDER_HOOK_FLAGS, RENDERER, TData, TRANSPLANTED_VIEWS_TO_REFRESH, TView} from '../interfaces/view';
|
||||
|
||||
|
||||
|
||||
@ -194,4 +194,24 @@ export function getLContainerActiveIndex(lContainer: LContainer) {
|
||||
|
||||
export function setLContainerActiveIndex(lContainer: LContainer, index: number) {
|
||||
lContainer[ACTIVE_INDEX] = index << ActiveIndexFlag.SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the `TRANSPLANTED_VIEWS_TO_REFRESH` counter on the `LContainer` as well as the parents
|
||||
* whose
|
||||
* 1. counter goes from 0 to 1, indicating that there is a new child that has a view to refresh
|
||||
* or
|
||||
* 2. counter goes from 1 to 0, indicating there are no more descendant views to refresh
|
||||
*/
|
||||
export function updateTransplantedViewCount(lContainer: LContainer, amount: 1|- 1) {
|
||||
lContainer[TRANSPLANTED_VIEWS_TO_REFRESH] += amount;
|
||||
let viewOrContainer: LView|LContainer = lContainer;
|
||||
let parent: LView|LContainer|null = lContainer[PARENT];
|
||||
while (parent !== null &&
|
||||
((amount === 1 && viewOrContainer[TRANSPLANTED_VIEWS_TO_REFRESH] === 1) ||
|
||||
(amount === -1 && viewOrContainer[TRANSPLANTED_VIEWS_TO_REFRESH] === 0))) {
|
||||
parent[TRANSPLANTED_VIEWS_TO_REFRESH] += amount;
|
||||
viewOrContainer = parent;
|
||||
parent = parent[PARENT];
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user