Skip to content

Commit 8b961fc

Browse files
refactor(Transition): Create '$transition$' and '$stateParams' injectables in Transition constructor
1 parent c9fcafb commit 8b961fc

File tree

8 files changed

+46
-51
lines changed

8 files changed

+46
-51
lines changed

src/path/pathFactory.ts

+28-42
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
/** @module path */ /** for typedoc */
22

33
import {extend, find, pick, omit, tail, mergeR, values, unnestR} from "../common/common";
4-
import {prop, propEq, not, curry} from "../common/hof";
4+
import {prop, propEq, not} from "../common/hof";
55

66
import {RawParams} from "../params/interface";
77
import {TreeChanges} from "../transition/interface";
8+
import {ViewConfig} from "../view/interface";
9+
import {_ViewDeclaration} from "../state/interface";
810

911
import {State, TargetState} from "../state/module";
1012
import {Node} from "../path/node";
11-
import {ResolveContext, Resolvable} from "../resolve/module";
12-
import {Transition} from "../transition/module";
13+
import {ResolveContext} from "../resolve/module";
1314
import {ViewService} from "../view/view";
1415

1516
/**
@@ -38,12 +39,18 @@ export class PathFactory {
3839
}
3940
return toPath;
4041
}
41-
42+
43+
/**
44+
* Creates ViewConfig objects and adds to nodes.
45+
*
46+
* On each Node, creates ViewConfig objects from the views: property of the node's state
47+
*/
4248
static applyViewConfigs($view: ViewService, path: Node[]) {
4349
return path.map(node => {
44-
let viewDecls = values(node.state.views || {});
45-
let viewConfigs = viewDecls.map(view => $view.createViewConfig(node, view)).reduce(unnestR, []);
46-
return extend(node, {views: viewConfigs})
50+
let viewDecls: _ViewDeclaration[] = values(node.state.views || {});
51+
let viewConfigs: ViewConfig[][] = viewDecls.map(view => $view.createViewConfig(node, view));
52+
node.views = viewConfigs.reduce(unnestR, []);
53+
return node;
4754
});
4855
}
4956

@@ -68,39 +75,32 @@ export class PathFactory {
6875
* Given an Node "toNode", return a new Node with param values inherited from the
6976
* matching node in fromPath. Only inherit keys that aren't found in "toKeys" from the node in "fromPath""
7077
*/
71-
let makeInheritedParamsNode = curry(function(_fromPath: Node[], _toKeys: string[], toNode: Node): Node {
78+
function makeInheritedParamsNode(toNode: Node): Node {
7279
// All param values for the node (may include default key/vals, when key was not found in toParams)
7380
let toParamVals = extend({}, toNode && toNode.paramValues);
7481
// limited to only those keys found in toParams
75-
let incomingParamVals = pick(toParamVals, _toKeys);
76-
toParamVals = omit(toParamVals, _toKeys);
77-
let fromParamVals = nodeParamVals(_fromPath, toNode.state) || {};
82+
let incomingParamVals = pick(toParamVals, toKeys);
83+
toParamVals = omit(toParamVals, toKeys);
84+
let fromParamVals = nodeParamVals(fromPath, toNode.state) || {};
7885
// extend toParamVals with any fromParamVals, then override any of those those with incomingParamVals
7986
let ownParamVals: RawParams = extend(toParamVals, fromParamVals, incomingParamVals);
8087
return new Node(toNode.state).applyRawParams(ownParamVals);
81-
});
88+
}
8289

8390
// The param keys specified by the incoming toParams
84-
return <Node[]> toPath.map(makeInheritedParamsNode(fromPath, toKeys));
91+
return <Node[]> toPath.map(makeInheritedParamsNode);
8592
}
8693

8794
/**
88-
* Given a path, upgrades the path to a Node[]. Each node is assigned a ResolveContext
89-
* and ParamValues object which is bound to the whole path, but closes over the subpath from root to the node.
90-
* The views are also added to the node.
95+
* Given a path of nodes, creates and binds a ResolveContext to each node.
96+
* The ResolveContext is used to inject functions from the proper scoping in the resolve tree.
9197
*/
92-
static bindTransNodesToPath(resolvePath: Node[]): Node[] {
98+
static bindResolveContexts(resolvePath: Node[]): Node[] {
9399
let resolveContext = new ResolveContext(resolvePath);
94-
// let paramValues = new ParamValues(resolvePath);
95-
96-
// Attach bound resolveContext and paramValues to each node
97-
// Attach views to each node
98-
resolvePath.forEach((node: Node) => {
100+
return resolvePath.map((node: Node) => {
99101
node.resolveContext = resolveContext.isolateRootTo(node.state);
100-
node.resolves['$stateParams'] = new Resolvable("$stateParams", () => node.paramValues, node.paramValues);
102+
return node;
101103
});
102-
103-
return resolvePath;
104104
}
105105

106106
/**
@@ -123,33 +123,19 @@ export class PathFactory {
123123
}
124124

125125
let from: Node[], retained: Node[], exiting: Node[], entering: Node[], to: Node[];
126-
// intermediate vars
127-
let retainedWithToParams: Node[], enteringResolvePath: Node[], toResolvePath: Node[];
128126

129127
from = fromPath;
130128
retained = from.slice(0, keep);
131129
exiting = from.slice(keep);
132130

133131
// Create a new retained path (with shallow copies of nodes) which have the params of the toPath mapped
134-
retainedWithToParams = retained.map(applyToParams);
135-
enteringResolvePath = toPath.slice(keep);
136-
// "toResolvePath" is "retainedWithToParams" concat "enteringResolvePath".
137-
toResolvePath = (retainedWithToParams).concat(enteringResolvePath);
138-
139-
// "to: is "toResolvePath" with ParamValues/ResolveContext added to each node and bound to the path context
140-
to = PathFactory.bindTransNodesToPath(toResolvePath);
141-
142-
// "entering" is the tail of "to"
143-
entering = to.slice(keep);
132+
let retainedWithToParams = retained.map(applyToParams);
133+
entering = toPath.slice(keep);
134+
to = (retainedWithToParams).concat(entering);
144135

145136
return { from, to, retained, exiting, entering };
146137
}
147138

148-
static bindTransitionResolve(treeChanges: TreeChanges, transition: Transition) {
149-
let rootNode = treeChanges.to[0];
150-
rootNode.resolves['$transition$'] = new Resolvable('$transition$', () => transition, transition);
151-
}
152-
153139
/**
154140
* Find a subpath of a path that stops at the node for a given state
155141
*

src/state/stateService.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ export class StateService {
275275

276276
let ref: TargetState = this.target(to, toParams, options);
277277
let latestSuccess: Transition = this.globals.successfulTransitions.peekTail();
278-
const rootPath = () => PathFactory.bindTransNodesToPath([new Node(this.stateRegistry.root())]);
278+
const rootPath = () => PathFactory.bindResolveContexts([new Node(this.stateRegistry.root())]);
279279
let currentPath: Node[] = latestSuccess ? latestSuccess.treeChanges().to : rootPath();
280280

281281
if (!ref.exists())

src/transition/transition.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {Resolvable} from "../resolve/module";
2020
import {TransitionService} from "./transitionService";
2121
import {ViewConfig} from "../view/interface";
2222
import {Rejection} from "./rejectFactory";
23+
import {Resolvables} from "../resolve/interface";
2324

2425

2526
let transitionCount = 0;
@@ -139,7 +140,15 @@ export class Transition implements IHookRegistry {
139140
let toPath = PathFactory.buildToPath(fromPath, targetState);
140141
toPath = PathFactory.applyViewConfigs(_transitionService.$view, toPath);
141142
this._treeChanges = PathFactory.treeChanges(fromPath, toPath, this._options.reloadState);
142-
PathFactory.bindTransitionResolve(this._treeChanges, this);
143+
144+
PathFactory.bindResolveContexts(this._treeChanges.to);
145+
146+
let rootResolvables: Resolvables = {
147+
"$transition$": new Resolvable('$transition$', () => this, this),
148+
"$stateParams": new Resolvable('$stateParams', () => this.params(), this.params())
149+
};
150+
let rootNode: Node = this._treeChanges.to[0];
151+
rootNode.resolveContext.addResolvables(rootResolvables, rootNode.state)
143152
}
144153

145154
$from() {

test/core/hookBuilderSpec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ describe('HookBuilder:', function() {
4646
// Transition from 'A' to 'A.B.C'
4747
let A = $state.target('A', null).$state();
4848
let path = [new Node(root), new Node(A)];
49-
path = PathFactory.bindTransNodesToPath(path);
49+
path = PathFactory.bindResolveContexts(path);
5050
trans = $trans.create(path, $state.target("A.B.C", null));
5151
hb = trans.hookBuilder();
5252
expect(hb.getOnBeforeHooks().length).toBe(0);
@@ -56,7 +56,7 @@ describe('HookBuilder:', function() {
5656
let B = $state.target('A.B', null).$state();
5757
let C = $state.target('A.B.C', null).$state();
5858
let fromPath = [new Node(root), new Node(A), new Node(B), new Node(C)];
59-
fromPath = PathFactory.bindTransNodesToPath(fromPath);
59+
fromPath = PathFactory.bindResolveContexts(fromPath);
6060
trans2 = $trans.create(fromPath, $state.target("A", null));
6161
hb2 = trans2.hookBuilder();
6262

test/core/resolveSpec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ beforeEach(function () {
8484

8585
function makePath(names: string[]): Node[] {
8686
let nodes = map(names, name => new Node(statesMap[name]));
87-
return PathFactory.bindTransNodesToPath(nodes);
87+
return PathFactory.bindResolveContexts(nodes);
8888
}
8989

9090
function getResolvedData(pathContext: ResolveContext) {
@@ -135,7 +135,7 @@ describe('Resolvables system:', function () {
135135
let ctx = new ResolveContext(path);
136136
let resolvableLocals = ctx.getResolvables(statesMap["C"]);
137137
let keys = Object.keys(resolvableLocals).sort();
138-
expect(keys).toEqual( ["$stateParams", "_A", "_A2", "_B", "_B2", "_C", "_C2" ] );
138+
expect(keys).toEqual( [ "_A", "_A2", "_B", "_B2", "_C", "_C2" ] );
139139
});
140140
});
141141

test/ng1/resolveSpec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ beforeEach(function () {
8181

8282
function makePath(names: string[]): Node[] {
8383
let nodes = map(names, name => new Node(statesMap[name]));
84-
return PathFactory.bindTransNodesToPath(nodes);
84+
return PathFactory.bindResolveContexts(nodes);
8585
}
8686

8787
function getResolvedData(pathContext: ResolveContext) {

test/ng1/transitionSpec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ describe('transition', function () {
7474
queue.flush($state);
7575
makeTransition = function makeTransition(from, to, options) {
7676
let fromState = targetState(from).$state();
77-
let fromPath = PathFactory.bindTransNodesToPath(fromState.path.map(state => new Node(state)));
77+
let fromPath = PathFactory.bindResolveContexts(fromState.path.map(state => new Node(state)));
7878
return $transitions.create(fromPath, targetState(to, null, options));
7979
};
8080
}));

test/ng1/viewSpec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ describe('view', function() {
6666
let $view = new ViewService();
6767
$view.viewConfigFactory("ng1", ng1ViewConfigFactory);
6868

69-
path = PathFactory.bindTransNodesToPath([root, state].map(_state => new Node(_state, {})));
69+
path = PathFactory.bindResolveContexts([root, state].map(_state => new Node(_state, {})));
7070
path = PathFactory.applyViewConfigs($view, path);
7171

7272
ctx = new ResolveContext(path);

0 commit comments

Comments
 (0)