示例
需求:用backbone.js和jquery實現一個可編輯的員工信息表格。
功能:1、錄入員工信息。2、刪除員工信息。3、雙擊表格可對員工信息進行修改。4、能對員工信息進行有效性校驗。5、能對員工信息進行持久化。
設計:
用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>