BackBone是JavaScript frameworks for creating MVC-like web applications,最近流行的用來創建單頁面web application的工具,遵循並使用了Restful JSON框架。html
Backbone經過提供模型Models、集合Collection、視圖View賦予了Web應用程序分層結構。經過如下方式實現分層結構:jquery
var view = new EmployeeView({model:employee});
也就是說model就是以這種方式和view進行關聯的web
將模型、集合、視圖與服務端的RESTful JSON接口鏈接。
Backbone必須依賴於 Underscore.js,DOM操做和AJAX請求依賴於第三方jQuery/Zepto/ender之一,也能夠經過 Backbone.setDomLibrary( lib ) 設置其餘的第三方庫。數據庫
特色json
示例app
需求:用backbone.js和jquery實現一個可編輯的員工信息表格。框架
功能:一、錄入員工信息。二、刪除員工信息。三、雙擊表格可對員工信息進行修改。四、能對員工信息進行有效性校驗。五、能對員工信息進行持久化。dom
設計:函數
用Employee類(繼承自Backbone.Model)表示員工信息,包含ID、姓名、性別、年齡和職位字段。工具
window.Employee = Backbone.Model.extend({ // 模型值校驗 validate:function(attrs){ for(var key in attrs){ if(attrs[key] == ''){ return key + "不能爲空"; } if(key == 'age' && isNaN(attrs.age)){ return "年齡必須是數字"; } } } });
聲明Employee類以後就能夠新增一個Employee的示例對象了:
var employee = new Employee();
Employee類中沒必要聲明ID、姓名等業務字段。當須要給employee設置這些信息時候,只須要調用
employee.set({'id':1,'name':'Jason'});
固然,若是須要對employee的信息進行校驗,須要給Employee類配置一個validate方法,這個方法的參數attrs就是set進去的json數據。這樣,當employee裏面的數據每次發生改變的時候都會先調用這個validate方法。
Model類定義好以後就能夠開始定義集合類了,在集合類裏面能夠對裏面的每一個Model進行增長,刪除等一系列操做,還能夠調用fetch方法從server端獲取集合的初始值。
window.EmployeeList = Backbone.Collection.extend({ model : Employee, // 持久化到本地數據庫 localStorage: new Store("employees"), }); window.Employees = new EmployeeList();
設置 localStorage屬性後Employees裏面的數據自動會同步保存到本地數據庫裏面,每當調用Employees.fetch()後又會從localStorage裏面恢復數據。
View類主要負責一切和界面相關的工做,好比綁定html模板,綁定界面元素的事件,初始的渲染,模型值改變後的從新渲染和界面元素的銷燬等:
window.EmployeeView = Backbone.View.extend({ tagName : 'tr', template : _.template($('#item-template').html()), events : { "dblclick td" : "edit", "blur input,select" : "close", "click .del" : "clear", }, initialize : function(){ // 每次更新模型後從新渲染 this.model.bind('change', this.render, this); // 每次刪除模型以後自動移除UI this.model.bind('destroy', this.remove, this); }, setText : function(){ var model = this.model; this.input = $(this.el).find('input,select'); this.input.each(function(){ var input = $(this); input.val(model.get(input.attr("name"))); }); }, close: function(e) { var input = $(e.currentTarget); var obj = {}; obj[input.attr('name')] = input.val(); this.model.save(obj); $(e.currentTarget).parent().parent().removeClass("editing"); }, edit : function(e){ // 給td加上editing樣式 $(e.currentTarget).addClass('editing').find('input,select').focus(); }, render: function() { $(this.el).html(this.template(this.model.toJSON())); // 把每一個單元格的值賦予隱藏的輸入框 this.setText(); return this; }, remove: function() { $(this.el).remove(); }, clear: function() { this.model.destroy(); } });
這個類裏面的代碼比較多,但主要和界面的渲染有關。一個 EmployeeView對象對應table裏面的一個tr元素。每次new一個EmployeeView對象的時候都會先調用initialize方 法,這個方法裏面綁定的事件確保了tr元素對應的model值每次發生改變或者被刪除時都會同步到界面。也就是說當每次操做界面對數據進行修改後都是先把 當前的變動保存到view綁定的model對象裏面,而後model裏面的事件機制會自動觸發一個"change"事件對界面進行修改。
template中使用的方法_.template($('#item- template').html())是前面提到的underscore.js中提供一個工具方法,能夠經過界面的HTML模板和一個JSON生成動態的 HTML,說白了就是把JSON裏面的值填充到HTML模板中對應的佔位符裏面去,牛X的是HTML模板裏面支持一些經常使用的邏輯表達式如 if,else,foreach等:
<script type="text/template" id="item-template"> <td><%= eid %></td> <td class="username"> <div class="display"><%= username %></div> <div class="edit"><input class="username" name="username"></input></div> </td> <td class="sex"> <div class="display"><%= sex=="1" ? "女":"男" %></div> <div class="edit"> <select name="sex" class="sex" style="width:45px"> <option value="0">男</option><option value="1">女</option> </select> </div> </td> <td class="age"> <div class="display"><%= age %></div> <div class="edit"> <input class="age" name="age"></input> </div> </td> <td class="position"> <div class="display"><%= position %></div> <div class="edit"> <input class="position" name="position"></input> </div> </td> <td> <a href="#" class="del">刪除</a> </td> </script>
setText方法主要負責把model裏面的數據設置到每一個tr裏面的隱藏輸入域裏面。
close方法被綁定到了input和select元素的blur事件中。當用 戶對單元格數據進行修改後都會把鼠標點擊到界面其餘地方而後輸入框會自動隱藏而且把修改的數據顯示在表格上面。close方法首先從當前被編輯的元素中拿 到最新值,而後封裝成一個對象,調用model的save方法後首先執行model的validate方法,若是校驗經過則保存到本地存儲並觸 發"change"事件。
最後還須要一個主界面View,這個View主要綁定了界面中的錄入表單的「增長」按鈕事件,Employees的相關事件以及頁面初始化時從本地存儲中恢復數據:
window.AppView = Backbone.View.extend({ el : $("#app"), events : { "click .#add-btn" : "createOnEnter" }, // 綁定collection的相關事件 initialize: function() { Employees.bind('add', this.addOne, this); // 調用fetch的時候觸發reset Employees.bind('reset', this.addAll, this); Employees.fetch(); }, createOnEnter : function(e) { var employee = new Employee(); var attr = {}; $('#emp-form input,#emp-form select').each(function(){ var input = $(this); attr[input.attr('name')] = input.val(); }); employee.bind('error',function(model,error){ alert(error); }); // set方法中會自動調用model的validate方法進行校驗,若是不經過則返回false if(employee.set(attr)){ Employees.create(employee); } }, addOne : function(employee){ employee.set({"eid":employee.get("eid")||Employees.length}); employee.bind('error',function(model,error){ alert(error); }); var view = new EmployeeView({model:employee}); $(".emp-table tbody").append(view.render().el); }, addAll : function(){ Employees.each(this.addOne); } });
initialize方法中綁定了Employees的add和reset事 件,也就是說每當往Employees中添加一個model的時候都會調用AppView的addOne方法,這個方法主要綁定了model的error 事件以及把EmployeeView生成的html插入到界面中的合適位置。
OK,萬事俱備,只欠啓動,整個應用的初始化方法就是AppView的initialize方法,所以只須要新建一個AppView就能夠了:
window.App = new AppView();
整個示例的JS代碼不多,因爲示例使用到了本地存儲,因此不要用IE運行示例
轉載自:http://weakfi.iteye.com/blog/1391990