Skip to content

Commit 12fbd8e

Browse files
committed
Pass arbitrary navigation params to router
Link components and other navigators can now pass to routers arbitrary params by using navigate(path, params, cb) method. On popstate/hashchange event those params are now {isPopState: true} so router could differentiate between different types of navigation.
1 parent 35034ad commit 12fbd8e

File tree

4 files changed

+40
-18
lines changed

4 files changed

+40
-18
lines changed

lib/AsyncRouteRenderingMixin.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ var AsyncRouteRenderingMixin = {
2929
this.replaceState({
3030
match: this.state.match,
3131
prefix: this.state.prefix,
32+
navigation: this.state.navigation,
3233
pendingChildren: handler
3334
});
3435

lib/Environment.js

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ function Environment() {
2222
/**
2323
* Notify routers about the change.
2424
*
25+
* @param {Object} navigation
2526
* @param {Function} cb
2627
*/
27-
Environment.prototype.notify = function notify(cb) {
28+
Environment.prototype.notify = function notify(navigation, cb) {
2829
var latch = this.routers.length;
2930

3031
if (latch === 0) {
@@ -40,17 +41,21 @@ Environment.prototype.notify = function notify(cb) {
4041

4142
ReactUpdates.batchedUpdates(function() {
4243
for (var i = 0, len = this.routers.length; i < len; i++) {
43-
this.routers[i].setPath(this.path, callback);
44+
this.routers[i].setPath(this.path, navigation, callback);
4445
}
4546
}.bind(this));
4647
}
4748

48-
Environment.prototype.makeHref = function navigate(path) {
49+
Environment.prototype.makeHref = function makeHref(path) {
4950
return path;
5051
}
5152

52-
Environment.prototype.navigate = function navigate(path, cb) {
53-
return this.setPath(path, cb);
53+
Environment.prototype.navigate = function navigate(path, navigation, cb) {
54+
if (typeof navigation === 'function' && cb === undefined) {
55+
cb = navigation;
56+
navigation = {};
57+
}
58+
return this.setPath(path, navigation, cb);
5459
}
5560

5661
/**
@@ -91,12 +96,12 @@ PathnameEnvironment.prototype.getPath = function() {
9196
return window.location.pathname;
9297
}
9398

94-
PathnameEnvironment.prototype.setPath = function(path, cb, retrospective) {
95-
if (!retrospective) {
99+
PathnameEnvironment.prototype.setPath = function(path, navigation, cb) {
100+
if (!navigation.isPopState) {
96101
window.history.pushState({}, '', path);
97102
}
98103
this.path = path;
99-
this.notify(cb);
104+
this.notify(navigation, cb);
100105
};
101106

102107
PathnameEnvironment.prototype.start = function() {
@@ -111,7 +116,7 @@ PathnameEnvironment.prototype.onPopState = function(e) {
111116
var path = window.location.pathname;
112117

113118
if (this.path !== path) {
114-
this.setPath(path, undefined, true);
119+
this.setPath(path, {isPopState: true});
115120
}
116121
};
117122

@@ -129,12 +134,12 @@ HashEnvironment.prototype.getPath = function() {
129134
return window.location.hash.slice(1) || '/';
130135
};
131136

132-
HashEnvironment.prototype.setPath = function(path, cb, retrospective) {
133-
if (!retrospective) {
137+
HashEnvironment.prototype.setPath = function(path, navigation, cb) {
138+
if (!navigation.isPopState) {
134139
window.location.hash = path;
135140
}
136141
this.path = path;
137-
this.notify(cb);
142+
this.notify(navigation, cb);
138143
};
139144

140145
HashEnvironment.prototype.start = function() {
@@ -149,7 +154,7 @@ HashEnvironment.prototype.onHashChange = function() {
149154
var path = window.location.hash.slice(1);
150155

151156
if (this.path !== path) {
152-
this.setPath(path, undefined, true);
157+
this.setPath(path, {isPopState: true});
153158
}
154159
};
155160

lib/Link.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ var Link = React.createClass({
3434
}
3535
},
3636

37+
_navigationParams: function() {
38+
var params = {};
39+
for (var k in this.props) {
40+
if (!this.constructor.propTypes[k]) {
41+
params[k] = this.props[k];
42+
}
43+
}
44+
return params;
45+
},
46+
3747
_createHref: function() {
3848
return this.props.global ?
3949
Environment.defaultEnvironment.makeHref(this.props.href) :
@@ -49,7 +59,7 @@ var Link = React.createClass({
4959
return Environment.defaultEnvironment.navigate(path, cb);
5060
}
5161

52-
return this.navigate(path, cb);
62+
return this.navigate(path, this._navigationParams(), cb);
5363
},
5464

5565
render: function() {

lib/RouterMixin.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ var RouterMixin = {
6969

7070
return {
7171
match: matchRoutes(this.getRoutes(), path),
72-
prefix: prefix
72+
prefix: prefix,
73+
navigation: {}
7374
};
7475
},
7576

@@ -104,9 +105,13 @@ var RouterMixin = {
104105
* @param {String} path
105106
* @param {Callback} cb
106107
*/
107-
navigate: function(path, cb) {
108+
navigate: function(path, navigation, cb) {
109+
if (typeof navigation === 'function' && cb === undefined) {
110+
cb = navigation;
111+
navigation = {};
112+
}
108113
path = join(this.state.prefix, path);
109-
this.props.environment.setPath(path, cb);
114+
this.props.environment.setPath(path, navigation, cb);
110115
},
111116

112117
/**
@@ -119,10 +124,11 @@ var RouterMixin = {
119124
* @param {String} path
120125
* @param {Callback} cb
121126
*/
122-
setPath: function(path, cb) {
127+
setPath: function(path, navigation, cb) {
123128
this.replaceState({
124129
match: matchRoutes(this.getRoutes(), path),
125130
prefix: this.state.prefix,
131+
navigation: navigation
126132
}, cb);
127133
},
128134

0 commit comments

Comments
 (0)