這不是一篇介紹seajs和backbone的文章,如果對這兩個庫不太了解,可以去他們官網查閱。歡迎轉載,注明出處:http://www.cnblogs.com/mapping/archive/2013/03/03/2941812.html
單頁面應用(spa:single page application)的業務邏輯多是比較復雜的,如果一次性把整個spa用到的文件加出估計得卡到不行,使用seajs可以很好的實現按需加載;使用backbone可以比較方便地實現數據、邏輯、表現分離,有人稱他為前端的MVC框架,又有人說他不算是MVC,這里就不做討論。
本文主要講解如何使用這兩個庫實現spa里模塊根據路由的自動加載
首先建立整個app的文件結構,如圖:

根目錄:autoload;
根目錄下index.html作為app首頁及入口,js目錄放置app的js文件;
js目錄中base放置基本的依賴js庫,main目錄放置app的框架代碼,module目錄就是用來放置各個模塊的功能js啦;
下一步就是把underscore、jquery、backbone源碼包裝成CMD規范(或參考這里)的文件,underscore和backbone已內置AMD接口,jquery最新版也已添加AMD的exports接口,如果是舊版的jquery需要return $.noConfilt(true),如下:
base/jquery.js
define('base/jquery', function(require) {
//jquery官方源碼
return $.noConflict(true);
});
base/underscore.js
define('base/underscore', function(require, exports, module) {
//underscore官方源碼
});
base/backbone.js
define('base/backbone', ['underscore', '$'], function(require, exports, module) {
this._ = require('underscore');
this.jQuery = require('$');
//backbone官方源碼
});
用過backbone的人都知道,使用他的路由功能來做spa非常方便,頁面較少的情況還可以,如果頁面一多,每次都要改路由配置;雖然backbone也支持多個Router對象,但每次新增模塊還是避免不了增加對應的router規則,就需要維護多個文件;而且配置的router越多,出現重復的概率就會越大,所以我們就要制定一個統一的router規則來實現模塊自動加載,其實就是把模塊的功能文件路徑及文件名作為參數傳給router處理函數,然后使用seajs的require.async方法去加載對應的文件,如下:
main/app.js
define('main/app', function(require, exports) {
var Backbone = require('backbone');
//配置路由
var autoRouter = Backbone.Router.extend({
routes: {
'': 'home',
'at/:module/:action(/*condition)': 'loadmodule'
},
home: function() {
this.loadmodule('home', 'index');
},
//按照at/module/action(/conditions)格式的請求自動加載模塊
loadmodule: function(md, ac, con) {
//將參數字符串'a:123/b:456'轉換為json對象{a:123, b:456}
var cj = {};
if(con && con.indexOf(':') > -1) {
con.replace(/(\w+)\s*:\s*([\w-]+)/g, function(a, b, c) {
b && (cj[b] = c);
});
} else {
cj = con;
}
//加載module目錄下對應的模塊
require.async(['module', md, ac].join('/'), function(cb) {
if(cb) {
cb(cj);
} else {
alert('模塊加載失敗!');
}
})
}
});
//定義全局變量App
window.App = {
Models: {},
Views: {},
Collections: {},
initialize: function() {
new autoRouter();
Backbone.history.start();
}
};
exports.run = App.initialize;
})
這里給路由一個非常yy的名稱at(把模塊@出來^_^),任何匹配'at/:module/:action(/*condition)'規則的路徑都會調用loadmodule方法,在這里condition是一個可選參數,如果要傳遞多個參數可以寫成‘a:123/b:456’的格式,loadmodule方法會將這個格式字符串轉換成json方便模塊里的代碼調用
autoRouter對象中還有一個空路由用於app的啟動,實際這條路由相當於'at/home/index';我們現在要做的就是在module目錄里加模塊文件了:
module/home/index.js
define('module/home/index', ['backbone'], function(reuqire) {
var Backbone = reuqire('backbone');
App.Models.Home = Backbone.Model.extend({});
App.Collections.Home = Backbone.Collection.extend({
model: App.Models.Home
});
App.Views.Home = Backbone.View.extend({
el: '#container',
initialize: function(c) {
this.Collections = c;
this.render();
},
render: function() {
var html = '';
this.Collections.each(function(m) {
html += '<div><a href="' + m.get('link') + '">' + m.get('name') + '</a></div>';
});
this.$el.html(html);
}
})
return function() {
//模擬數據
var hc = new App.Collections.Home();
hc.add([
{'name': '加載模塊A', 'link': '#at/m/a/name:moduleA/other:nothing'},
{'name': '加載模塊B', 'link': '#at/m/b'}
]);
new App.Views.Home(hc);
}
});
注意:每個自動加載的模塊都必須返回一個function,用於loadmodule方法callback,否則,提示模塊加載失敗;
這個function一般都用來將加出來的模塊初始化,如上面的index.js,這里會在頁面添加兩個鏈接用來加載模塊A和模塊B,再看下頁面index.html的代碼:
index.html
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>seajs+backbone實現單頁面模塊自動加載</title> </head> <body> <div id="container"> </div> <script type="text/javascript" src="js/base/sea.js"></script> <script type="text/javascript"> seajs.config({ base: '/js/', alias: { //基礎庫 'underscore': 'base/underscore', '$': 'base/jquery', 'backbone': 'base/backbone', 'app': 'main/app' } }); seajs.use('app', function(app) { app.run(); }); </script> </body> </html>
到這里,整個app已經可以運行啦

但是點擊“加載模塊A”或“加載模塊B”都會彈出模塊加載失敗,那是因為我們還沒添加這兩個模塊
module/m/a.js
define('module/m/a', ['$'], function(reuqire) {
var $ = reuqire('$');
return function(c) {
alert('moduleA加載成功,參數:' + $.param(c));
}
});
加載模塊A運行結果:

module/m/b.js
define('module/m/b', ['$'], function(reuqire) {
return function(c) {
alert('moduleB加載成功,參數:' + c);
}
});
加載模塊B運行結果:

好了,我們整個demo已經結束了,本文只是簡單介紹一種模塊自動加載的思路。
如果是做一個完整的spa,那么還有模塊依賴的樣式css文件、模板html文件需要加載以及從api拉取數據,這些功能借助seajs和backbone都可以比較方便實現,加載模板html文件你或許需要seajs的plugin-text.js插件
本文demo打包下載:autoload.zip
歡迎轉載,注明出處:http://www.cnblogs.com/mapping/archive/2013/03/03/2941812.html
