下載連接:spajavascript
主要功能以下:css
1.提供一個主應用框架,包含路由功能,視圖動態加載以及基本的錯誤處理html
2.腳本和模板的模塊化管理java
3.對子視圖的支持jquery
除了標題上的三個庫,還用到了一個很不錯的knockout擴展:git
knockout-amd-helpergithub
https://github.com/rniemeyer/knockout-amd-helpersweb
這個擴展主要目的是以module形式加載viewmodel和template,模板加載基於requirejs text,詳細內容能夠本身瞭解。服務器
腳手架包含如下內容:session
/index.html 應用框架頁
/scripts/main.js requirejs配置文件及應用程序入口
/scripts/lib 使用的第三方庫
/scripts/modules/*.js module腳本
/scripts/templates/*. tmpl.html module模板
/scripts/modules/app.js 主程序模型
首先看index.html
1 <html> 2 <head> 3 <link type="text/css" href="content/main.css" rel="stylesheet"/> 4 </head> 5 6 <body> 7 <!-- ko --> 8 <ul class="menus" data-bind="foreach:menus"> 9 <li><a href="#" data-bind="text:title,attr:{href:route}"></a></li> 10 </ul> 11 <div data-bind="module:moduleOptions,visible:!loading()"> 12 </div> 13 <div data-bind="visible:loading()"> 14 Loading... 15 </div> 16 <!-- /ko --> 17 <script type="text/javascript" data-main="scripts/main.js" src="scripts/lib/require.js"></script> 18 </body> 19 </html>
內容很簡單,包含菜單,內容視圖,以及一個加載狀態塊,最後的腳本是requirejs的主腳本。
main.js
1 require.config({ 2 baseUrl: '/scripts', 3 paths: { 4 "jquery": "lib/jquery-2.1.1", 5 "text": "lib/text", 6 "knockout":"lib/knockout-3.1.0.debug", 7 "ko-amd":"lib/knockout-amd-helpers", 8 "sammy":"lib/sammy-0.7.4", 9 "app":"modules/app" 10 }, 11 shim: { 12 "jquery":{ 13 exports:"jquery" 14 }, 15 "sammy": { 16 deps:["jquery"] 17 } 18 } 19 }); 20 21 require(["knockout", "app", "ko-amd"], function(ko, app){ 22 ko.bindingHandlers.module.baseDir = "modules"; 23 ko.amdTemplateEngine.defaultPath = "templates"; 24 25 ko.applyBindings(new app()); 26 });
require的config內容就不用說了,main.js另外配置了knockout-amd-helper的模塊路徑,加載並啓動了app.js
app.js
1 define(["knockout", "sammy"],function(ko, Sammy){ 2 return function(){ 3 var self = this; 4 5 self.menus = ko.observableArray([ 6 { title:"主頁", route:"#" }, 7 { title:"菜單一", route:"#/area1/list1" }, 8 { title:"菜單二", route:"#/area1/list2" } 9 ]); 10 11 self.loading = ko.observable(false); 12 self.moduleOptions = ko.observable({}); 13 self.loadError = ko.observableArray(false); 14 self.updateError = ko.observable(false); 15 16 self.updateError.subscribe(function(error){ 17 if (error){ 18 alert(error); 19 20 self.updateError(false); 21 } 22 }); 23 24 self.loadError.subscribe(function(error){ 25 if (error){ 26 self.moduleOptions({ name:"error", data: {app: self }}); 27 } 28 }); 29 30 Sammy(function(){ 31 this.get('#home', function () { 32 self.moduleOptions({ name: "home", data: { app: self }}); 33 self.loading(true); 34 }); 35 36 this.get(/\#\/([^/]+)\/([^/]+)/, function () { 37 var area = this.params.splat[0]; 38 var module = this.params.splat[1]; 39 40 self.moduleOptions({ name: area + "/" + module, data: { app:self, data:{} }}); 41 self.loading(true); 42 }); 43 44 this.get('/index.html', function () { this.app.runRoute('get', '#home') }); 45 }); 46 47 Sammy().run(); 48 } 49 });
主應用程序的ViewModel。這裏使用sammy作了簡單的路由,包含一個指向「#home」的路由和一個指向「#/{area}/{module}」的路由。
list1.js和list2.js,兩個模塊的ViewModel,具體代碼就不貼了,詳細內容能夠下載壓縮包查看。
list1演示了視圖模型的顯示,子視圖的加載,更新錯誤顯示(使用了alert,固然你能夠用其餘更風騷的方式顯示錯誤信息。),以及利用sessionStorage保存視圖狀態。
list2演示了視圖加載失敗的錯誤頁面跳轉。
home
list1
list2(error)
注意:不支持直接在文件系統預覽,你須要一個web服務器。
我使用的brackets編輯器自帶live preview功能,內置了簡單的web服務器,能夠直接預覽項目,固然你也能夠把代碼部署到web服務器中查看效果。