- 一.概述
- 二.REST Server的實現
- 2.1 REST API設計
- 2.2 數據庫設計
- 2.3 用MyBatis實現的DAO層
- 2.4 用Jersey實現的REST API
- 2.5 用Spring AOP實現的日志功能
- 三.前端的實現
- 3.1 顯示User列表
- 3.2 顯示User詳細信息
- 3.3 修改User信息
- 3.4 增加User
- 3.5 刪除User
- 3.6 添加validate
3.1 顯示User列表
界面如下:
1.html文件
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 3 <html> 4 <head> 5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 6 <script src="./js/jquery.js"></script> 7 <script src="./js/underscore.js"></script> 8 <script src="./js/backbone.js"></script> 9 <script src="./js/mvc1.js"></script><!-- 引入js文件 --> 10 <script type="text/template" id="user-item-template"><!-- html模板 --> 11 <span>(<%= id %>)</span><a href="#"><%= username %></a> 12 </script> 13 <link rel="stylesheet" type="text/css" href="./css/default.css" /> 14 <title>MVC 1</title> 15 </head> 16 <body> 17 <div id="main"> 18 <div id="left"> 19 <h3></h3> 20 <ul id="user-list"></ul> 21 </div> 22 <div id="right"></div> 23 </div> 24 </body> 25 </html>
mvc1.js文件
1 $(document).ready(function() { //注釋一 2 3 //定義User 4 var User = Backbone.Model.extend({ 5 }); 6 7 //定義UserList,是User的集合 8 var UserList = Backbone.Collection.extend({ 9 model : User, 10 url : "/backbone-sample/rest/user", //注釋二 11 /*****重載fetch**** 12 fetch : function() { 13 var self = this; 14 $.ajax({ 15 url: self.url, 16 cache:false, 17 type: 'GET', 18 async: true, 19 dataType: 'json', 20 timeout: 300000, 21 success: function( data, textStatus ) { 22 self.reset(data.user); 23 }, 24 }); 25 } 26 *************/ 27 }); 28 29 //定義UserItemView,用來顯示用戶列表中的一個條目 30 var UserItemView = Backbone.View.extend({ 31 tagName : "li", 32 userItemTemplate : _.template($("#user-item-template").html()), //綁定模板 33 render : function() { 34 this.$el.html(this.userItemTemplate(this.model.toJSON())); 35 return this; 36 }, 37 }); 38 39 //定義UserListView,用來顯示用戶列表 40 var UserListView = Backbone.View.extend({ 41 el : $("#main"), 42 initialize : function() { 43 this.userList = new UserList(); 44 this.userList.bind('reset', this.addAll, this); 45 this.userList.bind('all', this.render, this); //注釋三 46 this.userList.fetch({silent: true, success:function(collection, response){ //注釋四 47 if(response != null){ 48 collection.reset(response.user); 49 }else{ 50 userListView.render(); 51 } 52 }}); 53 }, 54 render : function() { 55 this.$("#left h3").html("Total Number:"+this.userList.length); 56 }, 57 addOne : function(user) { 58 var view = new UserItemView({model : user}); 59 this.$("#user-list").append(view.render().el); 60 }, 61 addAll : function() { 62 this.userList.each(this.addOne); 63 }, 64 }); 65 66 var userListView = new UserListView();//注釋五 67 });
注釋一:
一開始列表內容顯示不出來,找了半天沒找到原因,后來才發現是忘記加document.ready了。
注釋二:
Model 里面各有一個 url() 方法,和一個 urlRoot 屬性;Collection 里面有一個 url() 方法,它們的關系如下:
model.url() 返回模型資源在服務器上位置的相對 URL,默認的的實現是:如果模型包含在某個集合中,則生成 URL 的形式為:"/[collection.url]/[id]"; 如果模型不是集合的一部分,則 URL 形式為:"/[urlRoot]/id"。當然可以自己重載這個方法。
例如:一個 id 為101的模型,存儲在url為 "/documents/7/notes" 的 Colletion 中, 那么該模型的 URL 為:"/documents/7/notes/101"。
一般 GET、PUT、DELETE 是對某個特定模型的操作,會用 model.url() 得到帶有 id 的模型 URL;而 POST 操作是不知道模型id的,因此會用 collection.url() 得到集合的 URL。
在本例中,User 包含在 UserList 中,因此需要指定 UserList 的 url。
注釋三:
官網上對於bind方法的解釋:object.bind(event, callback, [context])
綁定 callback 函數到 object 對象。 當事件觸發時執行回調函數 callback 。如果一個頁面中有大量不同的事件,按照慣例使用冒號指定命名空間:"poll:start"或"change:selection"。當 callback 執行時提供第三個可選參數,可以為 this 指定上下文: model.bind(‘change’, this.render, this)
。綁定到特殊事件 "all" 的回調函數會在任意事件發生時被觸發,其第一個參數為事件的名稱。
注意到第三個參數,指定了第二個參數中this所代表的對象,例如:如果把this.userList.bind('add', this.addOne, this)
的this去掉,那么實際執行的時候,this.addOne中的this會是userList,實際上應該是userListView,於是就會出錯。
還有一點,在Todos這個例子中,所有的事件都是使用on來綁定事件的,也就是this.userList.on('add', this.addOne, this)
,我試了一下,二者沒有什么區別。查了一下源碼,on是定義在Backbone.Events中的一個函數,暫時還沒能理解為什么二者是等價的。
on: function(events, callback, context) {…} // Bind one or more space separated events, `events`, to a `callback` function. Passing `"all"` will bind the callback to all events fired.
注釋四:
官網上對於Collection的fetch函數的解釋如下:collection.fetch([options])
從服務器拉取集合的默認模型,成功接收數據后會重置(reset)集合。options 支持 success 和 error 回調函數,回調函數接收 (collection, response) 作為參數。 可以委托 Backbone.sync 在隨后處理個性化需求。處理 fetch 請求的服務器應當返回模型的 JSON 數組。
也就是調用 UserList 的 fetch() 方法時,會自動對 model.url() 的地址發出GET請求,然后將接收到的 JSON 數組作為參數來調用 reset() 方法自動設置UserList里面的User數組。
在我Server端,返回的Userlist格式如下:
{"user":[{"id":"63","username":"Andy0011","password":"123123","email":"111111@1.com","phone":""},…]}
注意到最外面會有一個 "user",這樣的格式不能被默認的fetch函數使用來給集合設值,因此需要自己重載fetch函數。
有兩個方法來實現:
第一個方法是在調用fetch函數的時候使用success回調函數,如注釋四 fetch() 中的代碼塊所示。
注意到有一個 silent: true,這是因為 fetch() 是異步的,當運行完之后自動觸發 reset 事件來給 userList 賦值,但是這個時候服務器端的JSON還沒有返回來,所以會報錯。加上 silent: true 之后,就不會自動觸發reset事件了,而是在success回調函數中使用 response.user 作為參數手動調用reset函數來給userList賦值。當然如果數據庫里面是空的就會返回空,因此需要判斷一下,區分處理。
第二個方法更加靈活了,是在var UserList = Backbone.Collection.extend({ })這個里面重載fetch函數,如11-26行注釋中的代碼塊所示。
這是一個典型的jQuery ajax調用,將請求設置為同步是為了解決上面那個silent: true的問題。
注釋五:
需要初始化一個 UserListView 類型的對象,頁面顯示的流程是:
調用 UserListView 的 initialize() 方法(42行),在其中將2個方法綁定到了 userList 的事件上(44-45行),並調用了 userList 的 fetch() 放來從Server 獲取數據並給其賦值(46行),在賦值的時候調用了 userList 的 reset() 方法(48行),這時候會觸發已綁定的 "reset" 事件,並調用 UserListView 的 addAll() 方法顯示列表內容,同時也會觸發 "all" 事件,並調用UserListView 的 render() 方法在列表頭部現實列表長度。在 addAll() 方法中為userList中的每一個元素調用 addOne() 方法(57行),在 addOne() 方法中會創建一個 UserItemView 並用它顯示列表的一個條目(61行)。