Backbone.js路由器匹配可选参数

时间:2012-03-10 18:32:04

标签: javascript regex backbone.js routes

我正在尝试创建一个可以匹配可选参数的骨干路由器。

请考虑以下代码:

routes: {  
  '/jobs'                                     : 'jobs',
  '/jobs/p:page'                              : 'jobs',
  '/jobs/job/:job_id'                         : 'jobs',
  '/jobs/p:page/job/:job_id'                  : 'jobs'
}

jobs: function(page, job_id){
   // do stuff here ....
}

如果我导航到URL abc.com/#/ jobs / p104 / 页面参数将 104 。但是,如果导航到abc.com/#/ jobs / job / 93 job_id 参数未定义,但页面< / strong>参数 93

所以Backbone的路由器基本上按顺序匹配路由哈希参数,而不是按名称匹配。

我知道解决方案是使用* splat并使用正则表达式拆分参数,但我似乎无法使正则表达式部分工作(我的正则表达式非常生疏)。有人可以帮忙吗?

如果有比使用* splat更好的解决方案,有人可以分享吗?

3 个答案:

答案 0 :(得分:21)

与其使用正则表达式相比,只有拥有第二个函数才会更容易,更不容易出错。你可能必须在this.jobs的初始化函数中绑定所有这个才能工作。

routes: {  
  '/jobs'                                     : 'jobs',
  '/jobs/p:page'                              : 'jobs',
  '/jobs/job/:job_id'                         : 'jobsId',
  '/jobs/p:page/job/:job_id'                  : 'jobs'
},

jobs: function(page, job_id){
   // do stuff here ....
},

jobsId: function(page, job_id){
   this.jobs(undefined, job_id
}

答案 1 :(得分:2)

试试这个(单个正则表达式,适用于所有输入格式)

var re = /\/jobs(?:\/p(\d+))?.*?(?:\/(\d+)|$)/;
var matches = 'abc.com/#/jobs/p104/4'.match(re);
var page=false;var job=false;
if (matches != null) {
    var page = matches[1] || false;
    var job = matches[2] || false;
}; 
alert("page:" + page + ",job:" + job)

**首先匹配pNNN段(如果它在那里),并且使用带有点.的非贪心量词,可以吃任何.*?来逐个爬行字符串,以便第二个group(just / NNN)也会匹配(如果存在)。 (?: exp )是非捕获组,他们分组,但他们不“记住”任何东西。

答案 2 :(得分:0)

如果你要做很多这些,你可以浏览一下this pattern来整理它们。但是,对于这些,以下正则表达式应该这样做:

/\/jobs\/p(\d+)/              => /jobs/pXXX
/\/jobs\/p(\d+)\/job\/(\d+)/  => /jobs/pXXX/job/XXX

然后,您可以将String.match与您检索到的splats一起使用,以提取相关的url片段。使用字符串代替splat变量:

var matches = '/jobs/p18'.match(/\/jobs\/p(\d+)/);
var page = matches[1];

var matches = '/jobs/p4/job/6/'.match(/\/jobs\/p(\d+)\/job\/(\d+)/);
var page = matches[1];
var job = matches[2];