之前在看durandal框架的文档的时候,在路由这一块,遇到一个特别的参数splat参数,当时看不明白是什么意思,现在明白了,特此记录
之前不明白很大一部分的原因是我把路由和路由指向的地址给搞混了,这两个是分开的概念,当前,主要是之前没有接触过这块,对于这个可以参考sammy.js的route来看。
举个例子:路由a/b/c和a/b/d是两个路由,但是这两个路由可能指向的是同一个模块(在durandal框架中),或者匹配这两个路由后进行的是同一个操作(在sammyjs中)。
通俗的说路由a/b/hello
和a/c/hello
跳转的html页面可以是同一个hello.html
文件。
现在说说路由的种类,一般有三种:
a/b/c
- 这种属于是固定的路由a/b/c/:name
- 这种属于带参数的路由,其中冒号开头的表示一个参数,也可以多个/a/b/:name/:age
,也可以a/b/(:name)
,表示参数可以省略,框架和库都有相关的获取参数值的方法a/b/c/*anything
- 这种叫做带splat参数的路由,在/a/b/c/
(注意末尾还有个斜杠)以后的字符串通通都会赋值给一个叫splat的参数。然后通过对应方法获取
下面是代码示例(druandal和sammy.js)
durandal生成route的代码:
define(["knockout", "durandal/app", ‘plugins/router‘], function(ko, app, router) {
var type = ko.observable("");
var id = ko.observable("");
var splat = ko.observable("");
return {
type: type,
id: id,
splat: splat,
navToDemo1: function() {
router.navigate(‘route-demo1‘)
},
navToDemo2: function() {
debugger;
var routeStr = ‘route-demo2‘;
if(this.type() !== ‘‘) {
routeStr += ‘/‘ + this.type();
} else {
return;
}
if(this.id() !== ‘‘) {
routeStr += ‘/‘ + this.id();
}
router.navigate(routeStr);
},
navToDemo3: function() {
debugger;
var routeStr = ‘route-demo3‘;
if(this.splat() !== ‘‘) {
routeStr += ‘/‘ + this.splat();
}
router.navigate(routeStr);
}
}
})
view:
<div class="module">
<div>
<p>debug 信息:</p>
<pre data-bind="text:ko.toJSON($root,null,2)"></pre>
</div>
<hr />
<div class="content">
<h1>导航页</h1>
<hr />
<p>route:route-demo1</p>
<p>规则:可以适配route-demo1</p>
<button class="btn btn-danger" data-bind="click:navToDemo1">nav to router-demo1</button>
<hr />
<p>route:route-demo2/:type(/:id)</p>
<p>规则:可以适配route-demo2/type和route-demo2/type/id</p>
<fieldset id="">
<legend>参数</legend>
<label for="">type:<input type="text" data-bind="textInput:type"/></label>
<label for="">id:<input type="text" data-bind="textInput:id"/></label>
</fieldset>
<button class="btn btn-success" data-bind="click:navToDemo2">nav to route-demo2</button>
<hr />
<p>route:route-demo3*details</p>
<p>规则:可以适配route-demo3(/anythings)</p>
<fieldset id="">
<legend>参数</legend>
<label for="">splat:<input type="text" data-bind="textInput:splat" style="width: 400px;"/></label>
</fieldset>
<button class="btn btn-default" data-bind="click:navToDemo3">nav to route-demo3</button>
</div>
</div>
define(["knockout"], function(ko) {
var args = ko.observable();
return {
args:args,
activate: function() {
debugger;
var argsArr = [].slice.call(arguments);
if(argsArr.length===0){
args(‘//通过路由传入的值为空‘);
}else{
args(ko.toJSON(arguments,null,2));
}
}
}
})
以下是sammy的demo代码:
//$.sammy 和 Sammy 等价 ,默认使用的app节点为body节点
var app = $.sammy(‘#main1‘, function(contextSammy) {
var sam = contextSammy;
//context 和 this 相等
debugger;
//http://sammyjs.org/docs/routes
//this.get, post, put, delete(del)
//#/, test/path/, #/my_path/:var
this.get(‘#/‘, function(context, nextRoute) {
debugger;
$(‘.welcome‘).text(‘Welcome! by $.sammy‘);
$.get(‘data/hello-world.html‘, function(data, status, promise) {
debugger;
// save the data somewhere
$(data).appendTo(‘.hello-world‘);
sam.log(‘step one is loaded;‘);
nextRoute();
});
}, function(context, nextRoute) {
debugger;
$.get(‘data/hello-world.html‘, function(data, status, promise) {
debugger;
// save the data somewhere
$(data).css({
‘font-size‘: ‘30px‘,
‘color‘: ‘green‘
}).appendTo(‘.hello-world‘);
sam.log(‘step two is loaded;‘);
nextRoute();
});
}, function() {
sam.log(‘all data is loaded;‘);
});
// route(verb, path, callback)
this.route(‘get‘, ‘#/hi-route‘, function(context, nextRoute) {
alert(‘hi by this.route‘);
});
// verb(path, callback)
this.get(‘#/hi-get‘, function(context, nextRoute) {
alert(‘hi by this.get‘);
});
this.put(‘#/post/form‘, function() {
alert(‘put to #/post/form‘);
return false;
});
this.get(/#\/color/, function() {
alert(‘start with color request‘);
});
this.get(‘#/by-name/:name‘, function() {
alert(this.params[‘name‘]);
});
this.get(/\#\/child\/(.*)/, function() {
alert(this.params[‘splat‘]);
});
}).run(‘#/‘);
结语:路由只要在web框架里面基本都有,比如react-route,vue-route等等,但是概念都是一样的