简体   繁体   English

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

[英]Backbone.js Router Matching Optional Parameters

I'm trying to create a backbone router that can match optional parameters. 我正在尝试创建一个可以匹配可选参数的骨干路由器。

Consider the following code: 请考虑以下代码:

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

If I navigate to URL abc.com/ #/jobs/p104/ the page parameter will be 104 . 如果我导航到URL abc.com/#/ jobs / p104 / 页面参数将为104 However, if navigate to abc.com/ #/jobs/job/93 , the job_id parameter is undefined but the page parameter is 93 . 但是,如果导航到abc.com/#/ jobs / job / 93 ,则job_id参数未定义,页面参数为93

So Backbone's router basically matches the routes hash parameters by order and not by name. 所以Backbone的路由器基本上按顺序匹配路由哈希参数而不是名称。

I know the solution would be to use a *splat and split the parameters with regex, but I can't seem to get the regex part to work (my regex is pretty rusty). 我知道解决方案是使用* splat并使用正则表达式拆分参数,但我似乎无法使正则表达式部分工作(我的正则表达式非常生疏)。 Can someone please help? 有人可以帮忙吗?

If there's a better solution than using *splat, can someone please share? 如果有比使用* splat更好的解决方案,有人可以分享吗?

Instead of messing with regexes it would be easier and less error prone just to have a second function. 而不是搞乱正则表达式,只是为了拥有第二个函数会更容易,更不容易出错。 You will probably have to bindAll this in an initialize function for this.jobs to work. 你可能必须在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
}

try this (single regex, works on all your input formats) 试试这个(单个正则表达式,适用于所有输入格式)

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)

**matches first the pNNN segment if it is there, and uses a non greedy quantifier with dot . **首先匹配pNNN段,如果它在那里,并使用带有点的非贪心量词. that can eat anything .*? 可以吃任何东西.*? to crawl up the string one by one, so that the second group (just /NNN) will also match if present. 逐个爬行字符串,以便第二组(仅/ NNN)也匹配(如果存在)。 the (?: exp ) are non-capturing groups, they group, but they don't "remember" anything. (?: exp )是非捕获组,它们分组,但它们不“记住”任何东西。

If you're going to be doing a lot of these, you might glance at this pattern for wrapping them up tidily. 如果你要做很多这些,你可能会看一下这种模式 ,整齐地包裹起来。 For just these, though, the following regexs ought to do it: 但是,对于这些,以下正则表达式应该这样做:

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

You can then use String.match with the splats you retrieve to extract the url fragments in question. 然后,您可以将String.match与您检索的String.match一起使用,以提取相关的url片段。 Using strings in place of a splat variable: 使用字符串代替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];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM