Skip to content

Commit ed844c6

Browse files
committed
Merge pull request angular-ui#1032 from angular-ui/types
Typed and optional parameters
2 parents 2aede6e + 7ef8f3c commit ed844c6

8 files changed

+1066
-276
lines changed

src/common.js

+4-20
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ function ancestors(first, second) {
4949
* @param {Object} object A JavaScript object.
5050
* @return {Array} Returns the keys of the object as an array.
5151
*/
52-
function keys(object) {
52+
function objectKeys(object) {
5353
if (Object.keys) {
5454
return Object.keys(object);
5555
}
@@ -96,8 +96,9 @@ function inheritParams(currentParams, newParams, $current, $to) {
9696
var parents = ancestors($current, $to), parentParams, inherited = {}, inheritList = [];
9797

9898
for (var i in parents) {
99-
if (!parents[i].params || !parents[i].params.length) continue;
100-
parentParams = parents[i].params;
99+
if (!parents[i].params) continue;
100+
parentParams = objectKeys(parents[i].params);
101+
if (!parentParams.length) continue;
101102

102103
for (var j in parentParams) {
103104
if (arraySearch(inheritList, parentParams[j]) >= 0) continue;
@@ -108,23 +109,6 @@ function inheritParams(currentParams, newParams, $current, $to) {
108109
return extend({}, inherited, newParams);
109110
}
110111

111-
/**
112-
* Normalizes a set of values to string or `null`, filtering them by a list of keys.
113-
*
114-
* @param {Array} keys The list of keys to normalize/return.
115-
* @param {Object} values An object hash of values to normalize.
116-
* @return {Object} Returns an object hash of normalized string values.
117-
*/
118-
function normalize(keys, values) {
119-
var normalized = {};
120-
121-
forEach(keys, function (name) {
122-
var value = values[name];
123-
normalized[name] = (value != null) ? String(value) : null;
124-
});
125-
return normalized;
126-
}
127-
128112
/**
129113
* Performs a non-strict comparison of the subset of two objects, defined by a list of keys.
130114
*

src/state.js

+28-25
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,14 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
4848

4949
// Build a URLMatcher if necessary, either via a relative or absolute URL
5050
url: function(state) {
51-
var url = state.url;
51+
var url = state.url, config = { params: state.params || {} };
5252

5353
if (isString(url)) {
54-
if (url.charAt(0) == '^') {
55-
return $urlMatcherFactory.compile(url.substring(1));
56-
}
57-
return (state.parent.navigable || root).url.concat(url);
54+
if (url.charAt(0) == '^') return $urlMatcherFactory.compile(url.substring(1), config);
55+
return (state.parent.navigable || root).url.concat(url, config);
5856
}
5957

60-
if ($urlMatcherFactory.isMatcher(url) || url == null) {
61-
return url;
62-
}
58+
if (!url || $urlMatcherFactory.isMatcher(url)) return url;
6359
throw new Error("Invalid url '" + url + "' in state '" + state + "'");
6460
},
6561

@@ -71,10 +67,8 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
7167
// Derive parameters for this state and ensure they're a super-set of parent's parameters
7268
params: function(state) {
7369
if (!state.params) {
74-
return state.url ? state.url.parameters() : state.parent.params;
70+
return state.url ? state.url.params : state.parent.params;
7571
}
76-
if (!isArray(state.params)) throw new Error("Invalid params in state '" + state + "'");
77-
if (state.url) throw new Error("Both params and url specicified in state '" + state + "'");
7872
return state.params;
7973
},
8074

@@ -94,16 +88,18 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
9488
},
9589

9690
ownParams: function(state) {
91+
state.params = state.params || {};
92+
9793
if (!state.parent) {
98-
return state.params;
94+
return objectKeys(state.params);
9995
}
100-
var paramNames = {}; forEach(state.params, function (p) { paramNames[p] = true; });
96+
var paramNames = {}; forEach(state.params, function (v, k) { paramNames[k] = true; });
10197

102-
forEach(state.parent.params, function (p) {
103-
if (!paramNames[p]) {
104-
throw new Error("Missing required parameter '" + p + "' in state '" + state.name + "'");
98+
forEach(state.parent.params, function (v, k) {
99+
if (!paramNames[k]) {
100+
throw new Error("Missing required parameter '" + k + "' in state '" + state.name + "'");
105101
}
106-
paramNames[p] = false;
102+
paramNames[k] = false;
107103
});
108104
var ownParams = [];
109105

@@ -782,8 +778,8 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
782778
toState = findState(to, options.relative);
783779

784780
if (!isDefined(toState)) {
785-
if (options.relative) throw new Error("Could not resolve '" + to + "' from state '" + options.relative + "'");
786-
throw new Error("No such state '" + to + "'");
781+
if (!options.relative) throw new Error("No such state '" + to + "'");
782+
throw new Error("Could not resolve '" + to + "' from state '" + options.relative + "'");
787783
}
788784
}
789785
if (toState[abstractKey]) throw new Error("Cannot transition to abstract state '" + to + "'");
@@ -808,14 +804,14 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
808804
// TODO: We may not want to bump 'transition' if we're called from a location change
809805
// that we've initiated ourselves, because we might accidentally abort a legitimate
810806
// transition initiated from code?
811-
if (shouldTriggerReload(to, from, locals, options) ) {
807+
if (shouldTriggerReload(to, from, locals, options)) {
812808
if (to.self.reloadOnSearch !== false) $urlRouter.update();
813809
$state.transition = null;
814810
return $q.when($state.current);
815811
}
816812

817-
// Normalize/filter parameters before we pass them to event handlers etc.
818-
toParams = normalize(to.params, toParams || {});
813+
// Filter parameters before we pass them to event handlers etc.
814+
toParams = filterByKeys(objectKeys(to.params), toParams || {});
819815

820816
// Broadcast start event and cancel the transition if requested
821817
if (options.notify) {
@@ -1090,7 +1086,12 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
10901086
* @returns {string} compiled state url
10911087
*/
10921088
$state.href = function href(stateOrName, params, options) {
1093-
options = extend({ lossy: true, inherit: false, absolute: false, relative: $state.$current }, options || {});
1089+
options = extend({
1090+
lossy: true,
1091+
inherit: false,
1092+
absolute: false,
1093+
relative: $state.$current
1094+
}, options || {});
10941095

10951096
var state = findState(stateOrName, options.relative);
10961097

@@ -1102,7 +1103,9 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
11021103
if (!nav || !nav.url) {
11031104
return null;
11041105
}
1105-
return $urlRouter.href(nav.url, normalize(state.params, params || {}), { absolute: options.absolute });
1106+
return $urlRouter.href(nav.url, filterByKeys(objectKeys(state.params), params || {}), {
1107+
absolute: options.absolute
1108+
});
11061109
};
11071110

11081111
/**
@@ -1132,7 +1135,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
11321135
// necessary. In addition to being available to the controller and onEnter/onExit callbacks,
11331136
// we also need $stateParams to be available for any $injector calls we make during the
11341137
// dependency resolution process.
1135-
var $stateParams = (paramsAreFiltered) ? params : filterByKeys(state.params, params);
1138+
var $stateParams = (paramsAreFiltered) ? params : filterByKeys(objectKeys(state.params), params);
11361139
var locals = { $stateParams: $stateParams };
11371140

11381141
// Resolve 'global' dependencies for the state, i.e. those not specific to a view.

0 commit comments

Comments
 (0)