Knockout+RequireJS+Sammy搭建簡單的SPA腳手架

下載連接: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>
View Code

內容很簡單,包含菜單,內容視圖,以及一個加載狀態塊,最後的腳本是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 });
View Code

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 });
View Code

主應用程序的ViewModel。這裏使用sammy作了簡單的路由,包含一個指向「#home」的路由和一個指向「#/{area}/{module}」的路由。

 

list1.js和list2.js,兩個模塊的ViewModel,具體代碼就不貼了,詳細內容能夠下載壓縮包查看。

list1演示了視圖模型的顯示,子視圖的加載,更新錯誤顯示(使用了alert,固然你能夠用其餘更風騷的方式顯示錯誤信息。),以及利用sessionStorage保存視圖狀態。

list2演示了視圖加載失敗的錯誤頁面跳轉。

 

home

list1

list2(error)

注意:不支持直接在文件系統預覽,你須要一個web服務器。 

我使用的brackets編輯器自帶live preview功能,內置了簡單的web服務器,能夠直接預覽項目,固然你也能夠把代碼部署到web服務器中查看效果。

相關文章
相關標籤/搜索