Skip to content

Commit fdd50ba

Browse files
committed
refactor(navcontroller): clean up and algorithm documented
1 parent 7385158 commit fdd50ba

File tree

2 files changed

+42
-30
lines changed

2 files changed

+42
-30
lines changed

src/navigation/nav-controller-base.ts

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,16 @@ export class NavControllerBase extends Ion implements NavController {
178178
}, done);
179179
}
180180

181+
// _queueTrns() adds a navigation stack change to the queue and schedules it to run:
182+
// 1. _nextTrns(): consumes the next transition in the queue
183+
// 2. _viewInit(): initializes enteringView if required
184+
// 3. _viewTest(): ensures canLeave/canEnter returns true, so the operation can continue
185+
// 4. _postViewInit(): add/remove the views from the navigation stack
186+
// 5. _transitionInit(): initializes the visual transition if required and schedules it to run
187+
// 6. _viewAttachToDOM(): attaches the enteringView to the DOM
188+
// 7. _transitionStart(): called once the transition actually starts, it initializes the Animation underneath.
189+
// 8. _transitionFinish(): called once the transition finishes
190+
// 9. _cleanup(): syncs the navigation internal state with the DOM. For example it removes the pages from the DOM or hides/show them.
181191
_queueTrns(ti: TransitionInstruction, done: Function): Promise<any> {
182192
let promise: Promise<any>;
183193
let resolve: Function = done;
@@ -288,7 +298,7 @@ export class NavControllerBase extends Ion implements NavController {
288298
}
289299

290300
// Only test canLeave/canEnter if there is transition
291-
const requiresTransition = (ti.enteringRequiresTransition || ti.leavingRequiresTransition) && enteringView !== leavingView;
301+
const requiresTransition = ti.requiresTransition = (ti.enteringRequiresTransition || ti.leavingRequiresTransition) && enteringView !== leavingView;
292302
if (requiresTransition) {
293303
// views have been initialized, now let's test
294304
// to see if the transition is even allowed or not
@@ -440,25 +450,26 @@ export class NavControllerBase extends Ion implements NavController {
440450
}
441451
}
442452

443-
if (ti.enteringRequiresTransition || ti.leavingRequiresTransition && enteringView !== leavingView) {
444-
// set which animation it should use if it wasn't set yet
445-
if (!opts.animation) {
446-
if (isPresent(ti.removeStart)) {
447-
opts.animation = (leavingView || enteringView).getTransitionName(opts.direction);
448-
} else {
449-
opts.animation = (enteringView || leavingView).getTransitionName(opts.direction);
450-
}
451-
}
452-
453-
// huzzah! let us transition these views
454-
this._transition(enteringView, leavingView, opts, ti.resolve);
455-
456-
} else {
453+
if (!ti.requiresTransition) {
454+
// transition is not required, so we are already done!
457455
// they're inserting/removing the views somewhere in the middle or
458456
// beginning, so visually nothing needs to animate/transition
459457
// resolve immediately because there's no animation that's happening
460458
ti.resolve(true, false);
459+
return true;
460+
}
461+
462+
// set which animation it should use if it wasn't set yet
463+
if (!opts.animation) {
464+
if (isPresent(ti.removeStart)) {
465+
opts.animation = (leavingView || enteringView).getTransitionName(opts.direction);
466+
} else {
467+
opts.animation = (enteringView || leavingView).getTransitionName(opts.direction);
468+
}
461469
}
470+
471+
// huzzah! let us transition these views
472+
this._transitionInit(enteringView, leavingView, opts, ti.resolve);
462473
return true;
463474
}
464475

@@ -552,7 +563,7 @@ export class NavControllerBase extends Ion implements NavController {
552563
}
553564
}
554565

555-
_transition(enteringView: ViewController, leavingView: ViewController, opts: NavOptions, resolve: TransitionResolveFn) {
566+
_transitionInit(enteringView: ViewController, leavingView: ViewController, opts: NavOptions, resolve: TransitionResolveFn) {
556567
// figure out if this transition is the root one or a
557568
// child of a parent nav that has the root transition
558569
this._trnsId = this._trnsCtrl.getRootTrnsId(this);
@@ -587,7 +598,7 @@ export class NavControllerBase extends Ion implements NavController {
587598

588599
// transition start has to be registered before attaching the view to the DOM!
589600
transition.registerStart(() => {
590-
this._trnsStart(transition, enteringView, leavingView, opts, resolve);
601+
this._transitionStart(transition, enteringView, leavingView, opts, resolve);
591602
if (transition.parent) {
592603
transition.parent.start();
593604
}
@@ -609,7 +620,7 @@ export class NavControllerBase extends Ion implements NavController {
609620
}
610621
}
611622

612-
_trnsStart(transition: Transition, enteringView: ViewController, leavingView: ViewController, opts: NavOptions, resolve: TransitionResolveFn) {
623+
_transitionStart(transition: Transition, enteringView: ViewController, leavingView: ViewController, opts: NavOptions, resolve: TransitionResolveFn) {
613624
assert(this.isTransitioning(), 'isTransitioning() has to be true');
614625

615626
this._trnsId = null;
@@ -650,7 +661,7 @@ export class NavControllerBase extends Ion implements NavController {
650661
// create a callback for when the animation is done
651662
transition.onFinish(() => {
652663
// transition animation has ended
653-
this._zone.run(this._trnsFinish.bind(this, transition, opts, resolve));
664+
this._zone.run(this._transitionFinish.bind(this, transition, opts, resolve));
654665
});
655666

656667
// get the set duration of this transition
@@ -683,17 +694,7 @@ export class NavControllerBase extends Ion implements NavController {
683694
}
684695
}
685696

686-
_viewsWillLifecycles(enteringView: ViewController, leavingView: ViewController) {
687-
if (enteringView || leavingView) {
688-
this._zone.run(() => {
689-
// Here, the order is important. WillLeave must be called before WillEnter.
690-
leavingView && this._willLeave(leavingView, !enteringView);
691-
enteringView && this._willEnter(enteringView);
692-
});
693-
}
694-
}
695-
696-
_trnsFinish(transition: Transition, opts: NavOptions, resolve: TransitionResolveFn) {
697+
_transitionFinish(transition: Transition, opts: NavOptions, resolve: TransitionResolveFn) {
697698
const hasCompleted = transition.hasCompleted;
698699
const enteringView = transition.enteringView;
699700
const leavingView = transition.leavingView;
@@ -746,6 +747,16 @@ export class NavControllerBase extends Ion implements NavController {
746747
resolve(hasCompleted, true, enteringName, leavingName, opts.direction);
747748
}
748749

750+
_viewsWillLifecycles(enteringView: ViewController, leavingView: ViewController) {
751+
if (enteringView || leavingView) {
752+
this._zone.run(() => {
753+
// Here, the order is important. WillLeave must be called before WillEnter.
754+
leavingView && this._willLeave(leavingView, !enteringView);
755+
enteringView && this._willEnter(enteringView);
756+
});
757+
}
758+
}
759+
749760
_insertViewAt(view: ViewController, index: number) {
750761
const existingIndex = this._views.indexOf(view);
751762
if (existingIndex > -1) {

src/navigation/nav-util.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ export interface TransitionInstruction {
189189
reject?: TransitionRejectFn;
190190
leavingRequiresTransition?: boolean;
191191
enteringRequiresTransition?: boolean;
192+
requiresTransition?: boolean;
192193
}
193194

194195
export enum ViewState {

0 commit comments

Comments
 (0)