Skip to content

Commit

Permalink
fix(resolve): Allow resolve's state context to be injected as $state$
Browse files Browse the repository at this point in the history
refactor(hooks): Move a) core resolvables and b) update globals to transition hooks.

Closes angular-ui/ui-router#3273
  • Loading branch information
christopherthielen committed Jan 20, 2017
1 parent f7f353e commit a06948b
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 61 deletions.
2 changes: 1 addition & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ module.exports = function (karma) {

module: {
loaders: [
{ test: /\.ts$/, loader: "awesome-typescript-loader?declaration=false&configFileName=test/tsconfig.json" }
{ test: /\.ts$/, loader: "awesome-typescript-loader?noEmit=true&configFileName=test/tsconfig.json" }
]
},

Expand Down
26 changes: 0 additions & 26 deletions src/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,30 +63,4 @@ export class Globals implements UIRouterGlobals {

/** @internalapi */
successfulTransitions = new Queue<Transition>([], 1);

/** @hidden */
constructor(transitionService: TransitionService) {
// TODO: This probably belongs in a hooks/globals.ts
const beforeNewTransition = ($transition$: Transition) => {

this.transition = $transition$;
this.transitionHistory.enqueue($transition$);

const updateGlobalState = () => {
this.successfulTransitions.enqueue($transition$);
this.$current = $transition$.$to();
this.current = this.$current.self;
copy($transition$.params(), this.params);
};

$transition$.onSuccess({}, updateGlobalState, {priority: 10000});

const clearCurrentTransition = () => { if (this.transition === $transition$) this.transition = null; };

$transition$.promise.then(clearCurrentTransition, clearCurrentTransition);

};

transitionService.onBefore({}, beforeNewTransition);
}
}
18 changes: 18 additions & 0 deletions src/hooks/coreResolvables.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/** @module hooks */ /** */
import { Transition } from "../transition/transition";
import { UIRouter } from "../router";
import { TransitionService } from "../transition/transitionService";

function addCoreResolvables(trans: Transition) {
trans.addResolvable({ token: UIRouter, deps: [], resolveFn: () => trans.router, data: trans.router }, "");
trans.addResolvable({ token: Transition, deps: [], resolveFn: () => trans, data: trans }, "");
trans.addResolvable({ token: '$transition$', deps: [], resolveFn: () => trans, data: trans }, "");
trans.addResolvable({ token: '$stateParams', deps: [], resolveFn: () => trans.params(), data: trans.params() }, "");

trans.entering().forEach(state => {
trans.addResolvable({ token: '$state$', deps: [], resolveFn: () => state, data: state }, state);
});
}

export const registerAddCoreResolvables= (transitionService: TransitionService) =>
transitionService.onCreate({}, addCoreResolvables);
42 changes: 42 additions & 0 deletions src/hooks/updateGlobals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/** @module hooks */ /** for typedoc */
import { Transition } from "../transition/transition";
import { copy } from "../common/common";
import { Globals } from "../globals";
import { TransitionService } from "../transition/transitionService";

/**
* A [[TransitionHookFn]] which updates global UI-Router state
*
* Registered using `transitionService.onBefore({}, updateGlobalState);`
*
* Before a [[Transition]] starts, updates the global value of "the current transition" ([[Globals.transition]]).
* After a successful [[Transition]], updates the global values of "the current state"
* ([[Globals.current]] and [[Globals.$current]]) and "the current param values" ([[Globals.params]]).
*
* See also the deprecated properties:
* [[StateService.transition]], [[StateService.current]], [[StateService.params]]
*/
const updateGlobalState = (trans: Transition) => {
let globals = trans.router.globals as Globals;
globals.transition = trans;
globals.transitionHistory.enqueue(trans);

const updateGlobalState = () => {
globals.successfulTransitions.enqueue(trans);
globals.$current = trans.$to();
globals.current = globals.$current.self;
copy(trans.params(), globals.params);
};

trans.onSuccess({}, updateGlobalState, {priority: 10000});

const clearCurrentTransition = () => {
// Do not clear globals.transition if a different transition has started in the meantime
if (globals.transition === trans) globals.transition = null;
};

trans.promise.then(clearCurrentTransition, clearCurrentTransition);
};

export const registerUpdateGlobalState = (transitionService: TransitionService) =>
transitionService.onBefore({}, updateGlobalState);
2 changes: 1 addition & 1 deletion src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class UIRouter {
transitionService: TransitionService = new TransitionService(this);

/** Global router state */
globals: UIRouterGlobals = new Globals(this.transitionService);
globals: UIRouterGlobals = new Globals();

/**
* Deprecated for public use. Use [[urlService]] instead.
Expand Down
14 changes: 0 additions & 14 deletions src/transition/transition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,27 +161,13 @@ export class Transition implements IHookRegistry {
TransitionHook.runAllHooks(onCreateHooks);

this.applyViewConfigs(router);
this.applyRootResolvables(router);
}

private applyViewConfigs(router: UIRouter) {
let enteringStates = this._treeChanges.entering.map(node => node.state);
PathFactory.applyViewConfigs(router.transitionService.$view, this._treeChanges.to, enteringStates);
}

private applyRootResolvables(router: UIRouter) {
let rootResolvables: Resolvable[] = [
new Resolvable(UIRouter, () => router, [], undefined, router),
new Resolvable(Transition, () => this, [], undefined, this),
new Resolvable('$transition$', () => this, [], undefined, this),
new Resolvable('$stateParams', () => this.params(), [], undefined, this.params())
];

let rootNode: PathNode = this._treeChanges.to[0];
let context = new ResolveContext(this._treeChanges.to);
context.addResolvables(rootResolvables, rootNode.state);
}

/**
* @internalapi
*
Expand Down
47 changes: 28 additions & 19 deletions src/transition/transitionService.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
/**
* @coreapi
* @module transition
*/ /** for typedoc */
*/
/** for typedoc */
import {
IHookRegistry, TransitionOptions, TransitionHookScope, TransitionHookPhase, TransitionCreateHookFn,
HookMatchCriteria, HookRegOptions, PathTypes, PathType, RegisteredHooks, IHookRegistration, TransitionHookFn,
TransitionStateHookFn
IHookRegistry, TransitionOptions, TransitionHookScope, TransitionHookPhase, TransitionCreateHookFn, HookMatchCriteria,
HookRegOptions, PathTypes, PathType, RegisteredHooks, TransitionHookFn, TransitionStateHookFn
} from "./interface";
import { Transition } from "./transition";
import { makeEvent, RegisteredHook } from "./hookRegistry";
import { TargetState } from "../state/targetState";
import { PathNode } from "../path/node";
import { ViewService } from "../view/view";
import { UIRouter } from "../router";
import { registerAddCoreResolvables } from "../hooks/coreResolvables";
import { registerRedirectToHook } from "../hooks/redirectTo";
import { registerOnExitHook, registerOnRetainHook, registerOnEnterHook } from "../hooks/onEnterExitRetain";
import { registerEagerResolvePath, registerLazyResolveState } from "../hooks/resolve";
import { registerLoadEnteringViews, registerActivateViews } from "../hooks/views";
import { registerUpdateGlobalState } from "../hooks/updateGlobals";
import { registerUpdateUrl } from "../hooks/url";
import { registerRedirectToHook } from "../hooks/redirectTo";
import { registerOnExitHook, registerOnRetainHook, registerOnEnterHook } from "../hooks/onEnterExitRetain";
import { registerLazyLoadHook } from "../hooks/lazyLoad";
import { TransitionEventType } from "./transitionEventType";
import { TransitionHook, GetResultHandler, GetErrorHandler } from "./transitionHook";
Expand Down Expand Up @@ -167,6 +169,7 @@ export class TransitionService implements IHookRegistry, Disposable {
* @hidden
*/
_deregisterHookFns: {
addCoreResolves: Function;
redirectTo: Function;
onExit: Function;
onRetain: Function;
Expand All @@ -175,6 +178,7 @@ export class TransitionService implements IHookRegistry, Disposable {
lazyResolve: Function;
loadViews: Function;
activateViews: Function;
updateGlobals: Function;
updateUrl: Function;
lazyLoad: Function;
};
Expand All @@ -195,7 +199,7 @@ export class TransitionService implements IHookRegistry, Disposable {
this._defineDefaultPaths();
this._defineDefaultEvents();

this._registerDefaultTransitionHooks();
this._registerCoreTransitionHooks();
}

/**
Expand Down Expand Up @@ -312,29 +316,34 @@ export class TransitionService implements IHookRegistry, Disposable {
}

/** @hidden */
private _registerDefaultTransitionHooks() {
private _registerCoreTransitionHooks() {
let fns = this._deregisterHookFns;

fns.addCoreResolves = registerAddCoreResolvables(this);

// Wire up redirectTo hook
fns.redirectTo = registerRedirectToHook(this);
fns.redirectTo = registerRedirectToHook(this);

// Wire up onExit/Retain/Enter state hooks
fns.onExit = registerOnExitHook(this);
fns.onRetain = registerOnRetainHook(this);
fns.onEnter = registerOnEnterHook(this);
fns.onExit = registerOnExitHook(this);
fns.onRetain = registerOnRetainHook(this);
fns.onEnter = registerOnEnterHook(this);

// Wire up Resolve hooks
fns.eagerResolve = registerEagerResolvePath(this);
fns.lazyResolve = registerLazyResolveState(this);

fns.eagerResolve = registerEagerResolvePath(this);
fns.lazyResolve = registerLazyResolveState(this);
// Wire up the View management hooks
fns.loadViews = registerLoadEnteringViews(this);
fns.activateViews = registerActivateViews(this);
fns.loadViews = registerLoadEnteringViews(this);
fns.activateViews = registerActivateViews(this);

// Updates global state after a transition
fns.updateGlobals = registerUpdateGlobalState(this);

// After globals.current is updated at priority: 10000
fns.updateUrl = registerUpdateUrl(this);
fns.updateUrl = registerUpdateUrl(this);

// Lazy load state trees
fns.lazyLoad = registerLazyLoadHook(this);
fns.lazyLoad = registerLazyLoadHook(this);
}
}

0 comments on commit a06948b

Please sign in to comment.