navigate to named routes
This commit is contained in:
parent
3e9e076c0b
commit
a22ce672aa
|
@ -27,6 +27,42 @@ let routes = {
|
|||
|
||||
let blank = false;
|
||||
|
||||
// Build a link to a page.
|
||||
let find = ({ to, params, query }) => {
|
||||
let $url;
|
||||
let re = /:[^\/]+/g;
|
||||
|
||||
// Skip empty objects.
|
||||
[ params, query ] = [_.isObject(params) ? params : {}, query ].map(o => _.pick(o, _.identity));
|
||||
|
||||
// Find among the routes.
|
||||
_.find(routes, (name, url) => {
|
||||
if (name != to) return;
|
||||
let matches = url.match(re);
|
||||
|
||||
// Do not match on the number of params.
|
||||
if (_.keys(params).length != (matches || []).length) return;
|
||||
|
||||
// Do not match on the name of params.
|
||||
if (!_.every(matches, m => m.slice(1) in params)) return;
|
||||
|
||||
// Fill in the params.
|
||||
$url = url.replace(re, m => params[m.slice(1)]);
|
||||
|
||||
// Found it.
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!$url) throw new Error(`path ${to} ${JSON.stringify(params)} is not recognized`);
|
||||
|
||||
// Append querystring.
|
||||
if (_.keys(query).length) {
|
||||
$url += "?" + _.map(query, (v, k) => `${k}=${v}`).join("&");
|
||||
}
|
||||
|
||||
return $url;
|
||||
};
|
||||
|
||||
export default React.createClass({
|
||||
|
||||
displayName: 'App.jsx',
|
||||
|
@ -37,44 +73,14 @@ export default React.createClass({
|
|||
|
||||
statics: {
|
||||
// Build a link to a page.
|
||||
link(to, params, query) {
|
||||
let $url;
|
||||
let re = /:[^\/]+/g;
|
||||
|
||||
// Skip empty objects.
|
||||
[ params, query ] = [_.isObject(params) ? params : {}, query ].map(o => _.pick(o, _.identity));
|
||||
|
||||
// Find among the routes.
|
||||
_.find(routes, (name, url) => {
|
||||
if (name != to) return;
|
||||
let matches = url.match(re);
|
||||
|
||||
// Do not match on the number of params.
|
||||
if (_.keys(params).length != (matches || []).length) return;
|
||||
|
||||
// Do not match on the name of params.
|
||||
if (!_.every(matches, m => m.slice(1) in params)) return;
|
||||
|
||||
// Fill in the params.
|
||||
$url = url.replace(re, m => params[m.slice(1)]);
|
||||
|
||||
// Found it.
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!$url) console.log(`path ${to} ${JSON.stringify(params)} is not recognized`);
|
||||
|
||||
// Append querystring.
|
||||
if (_.keys(query).length) {
|
||||
$url += "?" + _.map(query, (v, k) => `${k}=${v}`).join("&");
|
||||
}
|
||||
|
||||
return $url;
|
||||
link: (route) => {
|
||||
return find(route);
|
||||
},
|
||||
|
||||
// Route to a link.
|
||||
// TODO: make this a named route.
|
||||
navigate: navigate
|
||||
navigate: (route) => {
|
||||
let fn = _.isString(route) ? _.identity : find;
|
||||
navigate(fn(route));
|
||||
}
|
||||
},
|
||||
|
||||
// Show projects.
|
||||
|
|
|
@ -30,7 +30,7 @@ export default React.createClass({
|
|||
let [ owner, name ] = this.state.val.split('/');
|
||||
actions.emit('projects.add', { owner, name });
|
||||
// Redirect to the dashboard.
|
||||
App.navigate('/');
|
||||
App.navigate({ 'to': 'projects' });
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
|
|
|
@ -6,20 +6,20 @@ export default React.createClass({
|
|||
|
||||
displayName: 'Link.jsx',
|
||||
|
||||
_route(link, evt) {
|
||||
_navigate(link, evt) {
|
||||
App.navigate(link);
|
||||
evt.preventDefault();
|
||||
},
|
||||
|
||||
render() {
|
||||
let route = this.props.route;
|
||||
let link = App.link(route.to, route.params, route.query);
|
||||
let link = App.link(route);
|
||||
|
||||
return (
|
||||
<a
|
||||
{...this.props}
|
||||
href={'#!' + link}
|
||||
onClick={this._route.bind(this, link)}
|
||||
onClick={this._navigate.bind(this, link)}
|
||||
>
|
||||
{this.props.children}
|
||||
</a>
|
||||
|
|
Loading…
Reference in New Issue