navigate to named routes

This commit is contained in:
Radek Stepan 2016-01-17 17:24:26 +01:00
parent 3e9e076c0b
commit a22ce672aa
3 changed files with 46 additions and 40 deletions

View File

@ -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.

View File

@ -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() {

View File

@ -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>