是DEMO - User List 的擴展,增長查詢javascript
大致實現css
•建立Contact Modelhtml
1 var Contact = Backbone.Model.extend({ 2 defaults: { 3 name: '小強', 4 email: 'walker@dead.com' 5 }, 6 // validate user name 7 validate: function(attrs,options) { 8 if (attrs.name == "") { 9 return "what's the name?"; 10 }; 11 }, 12 // for user search 13 filter: function(query) { 14 if (typeof(query) === 'undefined' || query === null || query === '') return true; 15 query = query.toLowerCase(); 16 return this.get('name').toLowerCase().indexOf(query) != -1 || this.get('email').toLowerCase().indexOf(query) != -1; 17 } 18 });
•建立Contact Collectionjava
1 var Contacts = Backbone.Collection.extend({ 2 model: Contact, 3 localStorage: new Store('my-contacts') // 存至本地 4 });
•視圖jquery
- 每條聯繫人視圖 app
1 var ContactItemView = Backbone.View.extend({ 2 className: 'item', 3 template: _.template($('#tpl-item').html()), 4 events: { 5 'click': 'select' 6 }, 7 initialize: function() { 8 _.bindAll(this, 'select'); // select方法綁定到當前對象 9 this.model.bind('reset', this.render, this); 10 this.model.bind('change', this.render, this); 11 this.model.bind('destroy', this.remove, this); 12 if(this.model.view){ 13 this.model.view.remove(); 14 } 15 this.model.view = this; 16 }, 17 render: function() { 18 this.$el.html(this.template(this.model.toJSON())); 19 return this; 20 }, 21 select: function() { // 選擇某個聯繫人 22 appRouter.navigate('contacts/' + this.model.cid, { 23 trigger: true 24 }); 25 }, 26 active: function() { // 選中狀態 27 this.$el.addClass('active'); 28 }, 29 deactive: function() { // 未選中狀態 30 this.$el.removeClass('active'); 31 } 32 });
- 聯繫人列表視圖,實現功能:ide
渲染列表、實例化ContactItemView、添加Contact、查詢函數
1 var ContactListView = Backbone.View.extend({ 2 className: 'sidebar', 3 template: _.template($('#tpl-sidebar').html()), 4 events: { 5 'click footer button': 'create', // footer 標籤內的 button 標籤 click 事件 6 'click input': 'filter', 7 'keyup input': 'filter' 8 }, 9 initialize: function() { 10 _.bindAll(this, 'create', 'filter'); // 給 create,filter 函數綁定到當前對象 11 // model 監聽事件 12 this.model.bind('reset', this.renderAll, this); 13 this.model.bind('add', this.add, this); 14 this.model.bind('remove', this.remove, this); 15 }, 16 render: function() { 17 $(this.el).html(this.template()); 18 this.renderAll(); 19 return this; 20 }, 21 renderAll: function() { 22 this.$(".items").empty(); 23 this.model.each(this.renderOne, this); 24 this.filter(); 25 }, 26 renderOne: function(contact) { 27 var view = new ContactItemView({ 28 model: contact 29 }); 30 this.$(".items").append(view.render().el); 31 }, 32 create: function() { 33 var contact = new Contact(); 34 this.model.add(contact); 35 appRouter.navigate('contacts/' + contact.cid + '/edit', { 36 trigger:true 37 }); 38 }, 39 filter: function() { 40 var query = $('input', this.el).val(); 41 this.model.each(function(contact, element, index, list) { 42 contact.view.$el.toggle(contact.filter(query)); 43 }); 44 }, 45 active: function(item){ 46 if (this.activeItem) { 47 this.activeItem.view.deactive(); 48 } 49 this.activeItem = item; 50 if (this.activeItem) { 51 this.activeItem.view.active(); 52 } 53 }, 54 add: function(contact) { 55 this.renderOne(contact); 56 }, 57 remove: function(contact) { 58 console.log(contact); 59 } 60 });
- 顯示聯繫人信息視圖,實現:fetch
切換當前聯繫人,並展現this
1 var ShowView = Backbone.View.extend({ 2 className: 'show', 3 template: _.template($('#tpl-show').html()), 4 events: { 5 'click .edit': 'edit' 6 }, 7 initialize: function() { 8 _.bindAll(this, 'edit'); 9 }, 10 render: function() { 11 if(this.item){ 12 this.$el.html(this.template(this.item.toJSON())); 13 } 14 return this; 15 }, 16 change: function(item) { 17 this.item = item; 18 this.render(); 19 }, 20 edit: function() { 21 if (this.item) appRouter.navigate('contacts/' + this.item.cid + '/edit', { 22 trigger: true 23 }); 24 } 25 });
- 編輯聯繫人信息視圖,實現:
修改保存、刪除聯繫人
1 // edit usr contact view 2 var EditView = Backbone.View.extend({ 3 className: 'edit', 4 template: _.template($('#tpl-edit').html()), 5 events: { 6 'submit form': 'submit', 7 'click .save': 'submit', 8 'click .delete': 'remove' 9 }, 10 initialize: function() { 11 _.bindAll(this, 'submit', 'remove'); 12 }, 13 render: function() { 14 if(this.item){ 15 this.$el.html(this.template(this.item.toJSON())); 16 } 17 return this; 18 }, 19 change: function(item) { 20 this.item = item; 21 this.render(); 22 }, 23 submit: function() { 24 this.item.set(this.form()); 25 this.item.save(); 26 appRouter.navigate('contacts/' + this.item.cid, { 27 trigger:true 28 }); 29 return false; 30 }, 31 form: function() { 32 return { 33 name: this.$('form [name="name"]').val(), 34 email: this.$('form [name="email"]').val() 35 }; 36 }, 37 remove: function() { 38 this.item.destroy(); 39 this.item = null; 40 appRouter.navigate('', { 41 trigger: true 42 }); 43 } 44 });
- 主視圖,聯繫人展現、編輯管理視圖
實例化展現視圖、編輯視圖;切換展現視圖、編輯視圖
1 var MainView = Backbone.View.extend({ 2 className: 'main stack', 3 initialize: function() { 4 this.editView = new EditView(); 5 this.showView = new ShowView(); 6 }, 7 render: function() { 8 this.$el.append(this.showView.render().el); 9 this.$el.append(this.editView.render().el); 10 return this; 11 }, 12 edit: function(item) { 13 this.showView.$el.removeClass('active'); 14 this.editView.$el.addClass('active'); 15 this.editView.change(item); 16 }, 17 show: function(item) { 18 this.editView.$el.removeClass('active'); 19 this.showView.$el.addClass('active'); 20 this.showView.change(item); 21 } 22 });
- 總頁面視圖:
實例化列表視圖、主視圖
1 var AppView = Backbone.View.extend({ 2 className: 'contacts', 3 initialize: function() { 4 this.contactList = new ContactListView({ 5 model: this.model 6 }); 7 this.main = new MainView(); 8 this.vdiv = $('<div />').addClass('vdivide'); 9 this.model.fetch(); 10 this.render(); 11 }, 12 render: function() { 13 this.$el.append(this.contactList.render().el); 14 this.$el.append(this.vdiv); 15 this.$el.append(this.main.render().el); 16 $('#article').append(this.el); 17 return this; 18 }, 19 show: function(item){ 20 this.contactList.active(item); 21 this.main.show(item); 22 }, 23 edit: function(item){ 24 this.contactList.active(item); 25 this.main.edit(item); 26 } 27 });
•路由
1 dolymood.contacts = new Contacts(); 2 dolymood.appView = new AppView({ 3 model:dolymood.contacts 4 }); 5 dolymood.AppRouter = Backbone.Router.extend({ 6 routes: { 7 '': 'show', 8 'contacts/:id': 'show', 9 'contacts/:id/edit': 'edit' 10 }, 11 show: function(id) { 12 if(id !== undefined){ 13 dolymood.appView.show(this.getContact(id)); 14 } 15 else { 16 dolymood.appView.show(dolymood.contacts.first()); 17 } 18 }, 19 edit: function(id) { 20 if(id !== undefined){ 21 dolymood.appView.edit(this.getContact(id)); 22 } 23 }, 24 getContact: function(id) { 25 return dolymood.contacts.get(id); 26 } 27 });
注:v1.1.2 版本的Backbone.Collection,使用get函數,傳入cid來獲取model實例
•路由啓動
1 var appRouter = new dolymood.AppRouter(); 2 Backbone.history.start();
•html
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Backbone通信錄</title> 6 <link rel="stylesheet" href="css/application.css" type="text/css" charset="utf-8"> 7 </head> 8 <body> 9 <header id="header"><h1>Backbone通信錄</h1></header> 10 <article id="article"></article> 11 </body> 12 <script src="js/lib/jquery.js" type="text/javascript" charset="utf-8"></script> 13 <script src="js/lib/underscore.js" type="text/javascript" charset="utf-8"></script> 14 <script src="js/lib/backbone.js" type="text/javascript" charset="utf-8"></script> 15 <script src="js/lib/backbone-localstorage.js" type="text/javascript" charset="utf-8"></script> 16 17 <!-- 聯繫人 --> 18 <script type="text/template" id="tpl-item"> 19 <%= (name ? name : "<i>無名</i>") %> 20 </script> 21 22 <!-- 左邊的側邊條,包括聯繫人列表 --> 23 <script type="text/template" id="tpl-sidebar"> 24 <header> 25 <input type="search" placeholder="搜索" results="0" incremental="true" autofocus> 26 </header> 27 <div class="items"></div> 28 <footer> 29 <button>新建聯繫人</button> 30 </footer> 31 </script> 32 33 <!-- 顯示聯繫人詳細信息 --> 34 <script type="text/template" id="tpl-show"> 35 <header> 36 <a class="edit">編輯</a> 37 </header> 38 <div class="content"> 39 <p><label>姓名:<%= name %></label></p> 40 <p><label>郵箱:<%= email %></label></p> 41 </div> 42 </script> 43 44 <!-- 編輯聯繫人信息 --> 45 <script type="text/template" id="tpl-edit"> 46 <header> 47 <a class="save">保存</a> 48 <a class="delete">刪除</a> 49 </header> 50 <div class="content"> 51 <form> 52 <label> 53 <span>姓名:</span> 54 <input type="text" name="name" value="<%= name %>"> 55 </label> 56 <label> 57 <span>郵箱:</span> 58 <input type="email" name="email" value="<%= email %>"> 59 </label> 60 <button>保存</button> 61 </form> 62 </div> 63 </script> 64 <script src="js/app.js" type="text/javascript" charset="utf-8"></script> 65 </html>