這不是一篇介紹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