Skip to content

Commit 07f3a16

Browse files
committed
ref: Use event listeners to process nested frame entries in the correct order
1 parent c93514b commit 07f3a16

File tree

4 files changed

+43
-24
lines changed

4 files changed

+43
-24
lines changed

packages/core/ui/core/view-base/index.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
345345
private _androidView: Object;
346346
private _style: Style;
347347
private _isLoaded: boolean;
348+
private _isLoadingSubviews: boolean;
348349

349350
/**
350351
* @deprecated
@@ -637,6 +638,10 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
637638
return this._isLoaded;
638639
}
639640

641+
get isLoadingSubviews(): boolean {
642+
return this._isLoadingSubviews;
643+
}
644+
640645
get ['class'](): string {
641646
return this.className;
642647
}
@@ -686,14 +691,6 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
686691
this[name] = WrappedValue.unwrap(value);
687692
}
688693

689-
public loadSubviews(): void {
690-
this.eachChild((child) => {
691-
this.loadView(child);
692-
693-
return true;
694-
});
695-
}
696-
697694
@profile
698695
public onLoaded() {
699696
this.setFlag(Flags.superOnLoadedCalled, true);
@@ -705,7 +702,15 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
705702
this._cssState.onLoaded();
706703
this._resumeNativeUpdates(SuspendType.Loaded);
707704

708-
this.loadSubviews();
705+
this._isLoadingSubviews = true;
706+
707+
this.eachChild((child) => {
708+
this.loadView(child);
709+
710+
return true;
711+
});
712+
713+
this._isLoadingSubviews = false;
709714

710715
this._emit('loaded');
711716
}

packages/core/ui/frame/frame-common.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,31 @@ export class FrameBase extends CustomLayoutView {
119119
throw new Error(`Frame should not have a view. Use 'defaultPage' property instead.`);
120120
}
121121

122+
@profile
123+
public onLoaded() {
124+
const parentFrame = this.page?.frame;
125+
let pendingFrame: FrameBase;
126+
127+
// This frame is a nested frame as it resides inside the Page view of another frame
128+
if (parentFrame && parentFrame.isLoadingSubviews) {
129+
pendingFrame = parentFrame;
130+
} else {
131+
pendingFrame = this;
132+
}
133+
134+
// Process the entry of a nested frame once its parent has been loaded
135+
// or wait for it to be loaded in case it's not nested inside another frame
136+
pendingFrame.once(FrameBase.loadedEvent, () => {
137+
this.onFrameLoaded();
138+
});
139+
140+
super.onLoaded();
141+
}
142+
143+
public onFrameLoaded(): void {
144+
this._processNextNavigationEntry();
145+
}
146+
122147
public canGoBack(): boolean {
123148
let backstack = this._backStack.length;
124149
let previousForwardNotInBackstack = false;

packages/core/ui/frame/index.android.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -245,10 +245,8 @@ export class Frame extends FrameBase {
245245
super.onLoaded();
246246
}
247247

248-
public override loadSubviews(): void {
249-
// Process navigation entry after loading view but before loading children views, otherwise the navigation entries of nested frames will be processed first
250-
// and needed fragments won't have been attached yet
251-
this._processNextNavigationEntry();
248+
public onFrameLoaded(): void {
249+
super.onFrameLoaded();
252250

253251
// TODO: Check if this is still needed since there have been new improvements regarding fragment restoration
254252
// there's a bug with nested frames where sometimes the nested fragment is not recreated at all
@@ -266,12 +264,11 @@ export class Frame extends FrameBase {
266264

267265
this._frameCreateTimeout = null;
268266
}, 0);
269-
270-
super.loadSubviews();
271267
}
272268

273269
onUnloaded() {
274270
super.onUnloaded();
271+
275272
if (typeof this._frameCreateTimeout === 'number') {
276273
clearTimeout(this._frameCreateTimeout);
277274
this._frameCreateTimeout = null;

packages/core/ui/frame/index.ios.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,6 @@ export class Frame extends FrameBase {
7575
return this._ios;
7676
}
7777

78-
public override loadSubviews(): void {
79-
// Process navigation entry after loading view but before loading children views, otherwise the navigation entries of nested frames will be processed first
80-
// and needed fragments won't have been attached yet
81-
this._processNextNavigationEntry();
82-
83-
super.loadSubviews();
84-
}
85-
8678
public setCurrent(entry: BackstackEntry, navigationType: NavigationType): void {
8779
const current = this._currentEntry;
8880
const currentEntryChanged = current !== entry;
@@ -525,7 +517,7 @@ class UINavigationControllerImpl extends UINavigationController {
525517
}
526518
}
527519

528-
private animateWithDuration(navigationTransition: NavigationTransition, nativeTransition: UIViewAnimationTransition, transitionType: string, baseCallback: Function): void {
520+
private animateWithDuration(navigationTransition: NavigationTransition, nativeTransition: UIViewAnimationTransition, transitionType: string, baseCallback: () => void): void {
529521
const duration = navigationTransition.duration ? navigationTransition.duration / 1000 : CORE_ANIMATION_DEFAULTS.duration;
530522
const curve = _getNativeCurve(navigationTransition);
531523

0 commit comments

Comments
 (0)