前言
源碼地址
首先說下為什么想著寫backbone,因為我畢業以來工作用的第一個前端框架就是它了。老夫所在公司么比較注重穩定性,況且backbone靈活、輕巧,代碼量會少一點。
好吧,其實這的確是優點啦。
就如標題所言,本文主要擴展backbone路由處的方法。想嘛,在切換路由時可能需要在執行所切換路由對應的處理方法前或后做些操作,這時候發現backbone居然沒有提供,多么尷尬。如果使用過vue的朋友肯定知道vue-router可是提供了導航鉤子。
本人想擴展這個方法主要是在項目中遇到單頁面切換時:
比如從A頁面切換至B頁面時, 假使A頁面向后端請求很是耗時。這時候若是后端還未回復就切換至B頁面,假使這個請求在切換至B頁面之后失敗了,彈出了失敗提示框,很顯然這個是UX失敗。
可能有朋友會想到在彈出失敗提示時我判斷下當前url,然后決定是否彈出,這不失為個辦法,但是我想的是在切換之前判斷是否當前頁面有pending請求,若有cancel掉即可。所以上文提的需求就來了。
正文
首先呢咱們先擼個帶backbone路由功能界面,界面簡單,我就貼代碼了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<ul>
<li>
<a href="#pz">pz</a>
</li>
<li>
<a href="#wx">wx</a>
</li>
<li>
<a href="#sp">sp</a>
</li>
</ul>
<div id="page">
</div>
</body>
<script src="https://cdn.bootcss.com/jquery/1.11.0/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/underscore.js/1.6.0/underscore.js"></script>
<script src="https://cdn.bootcss.com/backbone.js/1.1.0/backbone.js"></script>
<script>
varRouter = Backbone.Router.extend({
initialize: function () {
console.log('initialize');
},
routes: {
'': 'pz',
'pz': 'pz',
'wx': 'wx',
'sp': 'sp'
},
pz: function () {
console.log('pz');
document.getElementById('page').innerHTML = 'Hello pz';
},
wx: function () {
console.log('wx');
document.getElementById('page').innerHTML = 'Hello wx';
},
sp: function () {
console.log('sp');
document.getElementById('page').innerHTML = 'Hello sp';
}
});
varrouter = newRouter();
Backbone.history.start();
</script>
</html>
這時候我們需要查看下backbone源碼。這里安利下bootcdn,下載各種js庫源碼在這里最方便不過了。就像在這里我用的是1.1.0版本的backbone(公司用的就是這個,就懶得換了)。
既然我們要在觸發具體路由方法之前加入before方法,那么很明顯是得分析下這個方法在源碼中的部分
image
很容易我們就可以定位到
image
到此就可以得到以下(當然依葫蘆畫瓢參照initialize方法可寫)
image
然后修改下我們的index.html
image
這時候切換可見
image
當然,直接修改源碼并不友好。如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<ul>
<li>
<a href="#pz">pz</a>
</li>
<li>
<a href="#wx">wx</a>
</li>
<li>
<a href="#sp">sp</a>
</li>
</ul>
<div id="page"></div>
</body>
<script src="https://cdn.bootcss.com/jquery/1.11.0/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/underscore.js/1.6.0/underscore.js"></script>
<script src="https://cdn.bootcss.com/backbone.js/1.1.0/backbone.js"></script>
<script>
Backbone.Router.prototype.before = function () { };
Backbone.Router.prototype.after = function () { };
Backbone.Router.prototype.route = function (route, name, callback) {
if (!_.isRegExp(route)) route = this._routeToRegExp(route);
if (_.isFunction(name)) {
callback = name;
name = '';
}
if (!callback) callback = this[name];
var router = this;
Backbone.history.route(route, function (fragment) {
var args = router._extractParameters(route, fragment);
router.before.apply(router, args);
callback && callback.apply(router, args);
router.after.apply(router, args);
router.trigger.apply(router, ['route:' + name].concat(args));
router.trigger('route', name, args);
Backbone.history.trigger('route', router, name, args);
});
return this;
};
var Router = Backbone.Router.extend({
initialize: function () {
console.log('initialize');
},
before: function () {
console.log('before');
},
after: function () {
console.log('after');
},
routes: {
'': 'pz',
'pz': 'pz',
'wx': 'wx',
'sp': 'sp'
},
pz: function () {
console.log('pz');
document.getElementById('page').innerHTML = 'Hello pz';
},
wx: function () {
console.log('wx');
document.getElementById('page').innerHTML = 'Hello wx';
},
sp: function () {
console.log('sp');
document.getElementById('page').innerHTML = 'Hello sp';
}
});
var router = newRouter();
Backbone.history.start();
</script>
</html>
后記
表示這個好坑,提示保存失敗。結果折騰到這么晚。郁悶死 =_=