昨天咱們一塊兒學習了Backbone,最後作了一個備忘錄的例子,說是作了不如說是看了下官方提供的例子,因此最終我感受咱們仍是沒能掌握Backbone,今天還得作個其它例子先。javascript
而後前面也只是草草學習了RequireJS,沒作demo,這個週末又在看電影打遊戲睡覺瞎折騰,轉眼就週日下午了,忽然詩性大起,因而做詩一首先:html
古有通宵看A片,今有徹夜碼代碼java
好吧,咱們開始今天的學習吧,咱們今天先用backbone作一個通信錄的東西,而後使用requireJS組裝之。jquery
部分參考:the5fire的技術博客git
作以前咱們先來個簡單的例子:github
1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 <head> 3 <title></title> 4 </head> 5 <body> 6 <div id="contactapp"> 7 <header> 8 <h1> 9 通信錄</h1> 10 </header> 11 <section id="main"> 12 <ul id="contact-list"> 13 </ul> 14 </section> 15 <div class="create"> 16 <input type="button" value="增長(彈出框)" id="addDia" /> 17 </div> 18 </div> 19 </body> 20 <script src="js/jquery.js" type="text/javascript"></script> 21 <script src="js/underscore.js" type="text/javascript"></script> 22 <script src="js/backbone.js" type="text/javascript"></script> 23 <script type="text/javascript"> 24 (function ($) { 25 var Contact = Backbone.Model.extend({ 26 //建立一個contact對象,擁有name屬性 27 name: null 28 }); 29 var ContackList = Backbone.Collection.extend({ 30 initialize: function (models, options) { 31 //contact集合 32 this.bind('add', options.view.addOne); 33 } 34 }); 35 var AppView = Backbone.View.extend({ 36 el: $('body'), 37 initialize: function () { 38 //實例化集合,並傳入AppView對象 39 this.contacts = new ContackList(null, { view: this }); 40 }, 41 events: { 42 'click #addDia': 'addDia' 43 }, 44 addDia: function () { 45 var name = prompt('請輸入姓名'); 46 var c = new Contact({ name: name }); 47 this.contacts.add(c); 48 }, 49 addOne: function (model) { 50 $('#contact-list').append('<li>' + model.get('name') + '</li>'); 51 } 52 }); 53 var app = new AppView(); 54 })(jQuery); 55 </script> 56 </html>
PS:感謝the5fire給出的例子,我和個人小夥伴一下都明白了。。。。web
以上代碼涉及到Backbone三個部分:View、Model、Collection,咱們在addOne裏面使用了jquery綁定dom之後會將之消除。ajax
各位請看這個代碼:api
this.bind('add', options.view.addOne);
在集合中綁定了add事件,在addDia最後執行了,而後觸發集合的事件,才最後將dom添加完成。數組
the5fire關於backbone的文章寫的很好(http://www.the5fire.com),咱們一塊兒來看看順便回顧下咱們的知識。
Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); } }); var man = new Man;
這個是一個model最簡單的model,initialize中的方法一來就會執行,這裏就會彈出框:
Man = Backbone.Model.extend({ initialize: function () { alert('Hey, you create me!'); }, defaults: { name: '張三', age: '38' } }); var man = new Man; alert(man.get('name')); //man.set({ name: 'the5fire', age: '10' });
如果不賦值就使用默認值,如果賦值則採用給的值。
Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); //初始化時綁定監聽 this.bind("change:name",function(){ var name = this.get("name"); alert("你改變了name屬性爲:" + name); }); }, defaults: { name:'張三', age: '38' }, aboutMe: function(){ return '我叫' + this.get('name') + ',今年' + this.get('age') + '歲'; } }); var man = new Man; man.set({name:'the5fire'}) //觸發綁定的change事件,alert。
能夠定義方法aboutMe,也能夠在initialize中綁定事件以監聽某個屬性的變化。
Man = Backbone.Model.extend({ initialize: function () { this.bind("error", function (model, error) { alert(error); }); }, validate: function (attributes) { if (attributes.name == '') { return "name不能爲空!"; } }, }); var man = new Man; man.set({ name: '' }); //根據驗證規則,彈出錯誤提示。
此處驗證不經過便會觸發錯誤提示。
PS:經測試並無提示,問題後面跟進
PS:最後證實有反應,我調試頁面用錯了
對象持久化能夠是服務器也能夠是本地存儲,具體就不展開了。
集合其實就是model的有序集合,通過週末的學習,咱們應該比較熟悉了:
Book = Backbone.Model.extend({ defaults: { // 感謝網友藍色動力指正改成defaults title: 'default' }, initialize: function () { //alert('Hey, you create me!'); } }); BookShelf = Backbone.Collection.extend({ model: Book }); var book1 = new Book({ title: 'book1' }); var book2 = new Book({ title: 'book2' }); var book3 = new Book({ title: 'book3' }); //var bookShelf = new BookShelf([book1, book2, book3]); //注意這裏面是數組,或者使用add var bookShelf = new BookShelf; bookShelf.add(book1); bookShelf.add(book2); bookShelf.add(book3); bookShelf.remove(book3); //基於underscore這個js庫,還可使用each的方法獲取collection中的數據 bookShelf.each(function (book) { alert(book.get('title')); });
咱們如果要與服務器通信獲取數據,須要先爲bookshelf定義url:
bookShelf.fetch({ url: '/getbooks/', success: function (collection, response) { collection.each(function (book) { alert(book.get('title')); }); }, error: function () { alert('error'); } });
//對應的BookShelf的返回格式以下: [{'title':'book1'},{'title':'book2'}.....]
此後咱們須要將頁面的dom與數據同步,因此會用到reset事件;
bookShelf.bind('reset',showAllBooks); showAllBooks = function(){ bookShelf.each(function(book){ //將book數據渲染到頁面。 }); }
1 <html> 2 <head> 3 <title>the5fire-backbone-collection</title> 4 </head> 5 <body> 6 </body> 7 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script> 8 <script src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.4/underscore-min.js"></script> 9 <script src="http://ajax.cdnjs.com/ajax/libs/backbone.js/0.3.3/backbone-min.js"></script> 10 <script> 11 (function ($) { 12 //collection是一個簡單的models的有序集合 13 //一、一個簡單的例子 14 15 Book = Backbone.Model.extend({ 16 defaults : { // 感謝網友藍色動力指正改成defaults 17 title:'default' 18 }, 19 initialize: function(){ 20 //alert('Hey, you create me!'); 21 } 22 }); 23 BookShelf = Backbone.Collection.extend({ 24 model : Book 25 }); 26 27 var book1 = new Book({title : 'book1'}); 28 var book2 = new Book({title : 'book2'}); 29 var book3 = new Book({title : 'book3'}); 30 31 //var bookShelf = new BookShelf([book1, book2, book3]); //注意這裏面是數組,或者使用add 32 var bookShelf = new BookShelf; 33 bookShelf.add(book1); 34 bookShelf.add(book2); 35 bookShelf.add(book3); 36 bookShelf.remove(book3); 37 /* 38 for(var i=0; i<bookShelf.models.length; i++) { 39 alert(bookShelf.models[i].get('title')); 40 } 41 */ 42 //基於underscore這個js庫,還可使用each的方法獲取collection中的數據 43 bookShelf.each(function(book){ 44 alert(book.get('title')); 45 }); 46 47 //二、使用fetch從服務器端獲取數據,使用reset渲染 48 bookShelf.bind('reset', showAllBooks); 49 bookShelf.fetch({url:'/getbooks/',success:function(collection,response){ 50 collection.each(function(book){ 51 alert(book.get('title')); 52 }); 53 },error:function(){ 54 alert('error'); 55 }}); 56 showAllBooks = function(){ 57 bookShelf.each(function(book){ 58 //將book數據渲染到頁面。 59 }); 60 } 61 //上述代碼僅僅均爲可正常執行的代碼,不過關於服務器端的實例在後面會有。 62 })(jQuery); 63 </script> 64 </html>
以前咱們學習的時候好像錯過了Router了,路由的出現是想控制URL呢,Backbone.Router會把#標籤當作url路徑。
1 <html> 2 <head> 3 <title>the5fire-backbone-router</title> 4 </head> 5 <body> 6 <a href="#/posts/120">Post 120</a> 7 <a href="#/download/user/images/hey.gif">download gif</a> 8 <a href="#/dashboard/graph">Load Route/Action View</a> 9 </body> 10 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script> 11 <script src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.4/underscore-min.js"></script> 12 <script src="http://documentcloud.github.com/backbone/backbone-min.js"></script> 13 <script> 14 (function ($) { 15 //Backbone中的router,見名知意,router有路由的意思,顯然這裏是要控制url的。 16 //Backbone.Router會把你鏈接中的#標籤當作是url路徑 17 /** 18 //一、來看一個簡單的例子 19 var AppRouter = Backbone.Router.extend({ 20 routes: { 21 "*actions" : "defaultRoute" 22 }, 23 defaultRoute : function(actions){ 24 alert(actions); 25 } 26 }); 27 28 var app_router = new AppRouter; 29 30 Backbone.history.start(); 31 32 33 //二、既然是對url進行匹配那麼它應該不只僅只是簡單的靜態匹配,應該具備傳遞參數的功能,因此下面再來一個動態的router的例子. 34 var AppRouter = Backbone.Router.extend({ 35 routes: { 36 "/posts/:id" : "getPost", 37 "*actions" : "defaultRoute" 38 }, 39 getPost: function(id) { 40 alert(id); 41 }, 42 defaultRoute : function(actions){ 43 alert(actions); 44 } 45 }); 46 47 var app_router = new AppRouter; 48 49 Backbone.history.start(); 50 **/ 51 //從上面已經能夠看到匹配#標籤以後內容的方法,有兩種:一種是用「:」來把#後面的對應的位置做爲參數;還有一種是「*」,它能夠匹配全部的url,下面再來演練一下。 52 var AppRouter = Backbone.Router.extend({ 53 routes: { 54 "/posts/:id" : "getPost", 55 "/download/*path": "downloadFile", //對應的連接爲<a href="#/download/user/images/hey.gif">download gif</a> 56 "/:route/:action": "loadView", //對應的連接爲<a href="#/dashboard/graph">Load Route/Action View</a> 57 "*actions" : "defaultRoute" 58 }, 59 getPost: function(id) { 60 alert(id); 61 }, 62 defaultRoute : function(actions){ 63 alert(actions); 64 }, 65 downloadFile: function( path ){ 66 alert(path); // user/images/hey.gif 67 }, 68 loadView: function( route, action ){ 69 alert(route + "_" + action); // dashboard_graph 70 } 71 }); 72 73 var app_router = new AppRouter; 74 75 Backbone.history.start(); 76 77 })(jQuery); 78 </script> 79 80 </html>
咱們暫時無論這個,不然任務完成不了了。
這個看完,咱們就要繼續今天的學習了,這裏用了太多時間啦。
backbone的view是用來顯示model數據到頁面的,同時監聽dom事件並相應變化。
來看看咱們的頁面主體:
1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 <head> 3 <title></title> 4 </head> 5 <body> 6 <div id="search_container"> 7 </div> 8 <script type="text/template" id="search_template"> 9 <label><%= search_label %></label> 10 <input type="text" id="search_input" /> 11 <input type="button" id="search_button" value="Search" /> 12 </script> 13 </body> 14 <script src="js/jquery.js" type="text/javascript"></script> 15 <script src="js/underscore.js" type="text/javascript"></script> 16 <script src="js/backbone.js" type="text/javascript"></script> 17 <script type="text/javascript"> 18 (function ($) { 19 //此處添加下面的試驗代碼 20 })(jQuery); 21 </script> 22 </html>
該屬性引用dom中的一些元素,每一個view都會有這個屬性,沒有聲明就默認建立空div
(function ($) { SearchView = Backbone.View.extend({ initialize: function () { //this.render(); }, render: function () { //使用underscore這個庫,來編譯模板 var template = _.template($("#search_template").html(), {}); //加載模板到對應的el屬性中 //this.el.html(template); //感謝 子不語同窗指正。 $(this.el).html(template); } }); var searchView = new SearchView({ el: $("#search_container") }); searchView.render(); //這個reander的方法能夠放到view的構造函數中 })(jQuery);
[這裏有一個錯誤,由於這個例子裏沒有傳入search_label這個變量,因此你運行的時候要把html的模板中的那個變量改掉才行。]
(function ($) { SearchView = Backbone.View.extend({ initialize: function () { this.render(); }, render: function () { //使用underscore這個庫,來編譯模板 var template = _.template($("#search_template").html(), {}); //加載模板到對應的el屬性中 //this.el.html(template); $(this.el).html(template); }, events: { //就是在這裏綁定的 'click input[type=button]': 'doSearch' //定義類型爲button的input標籤的點擊事件,觸發函數doSearch }, doSearch: function (event) { alert("search for " + $("#search_input").val()); } }); var searchView = new SearchView({ el: $("#search_container") }); })(jQuery);
此處的模板,就是以數據替換其中的特殊標籤<%= search_label %>
1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 <head> 3 <title></title> 4 </head> 5 <body> 6 <div id="search_container"> 7 </div> 8 <script type="text/template" id="search_template"> 9 <label><%= search_label %></label> 10 <input type="text" id="search_input" /> 11 <input type="button" id="search_button" value="Search" /> 12 </script> 13 </body> 14 <script src="js/jquery.js" type="text/javascript"></script> 15 <script src="js/underscore.js" type="text/javascript"></script> 16 <script src="js/backbone.js" type="text/javascript"></script> 17 <script type="text/javascript"> 18 (function ($) { 19 SearchView = Backbone.View.extend({ 20 initialize: function () { 21 this.render('the5fire'); 22 }, 23 render: function (search_label) { 24 //使用underscore這個庫,來編譯模板 25 var template = _.template($("#search_template").html(), { search_label: search_label }); 26 //加載模板到對應的el屬性中 27 $(this.el).html(template); 28 }, 29 events: { //就是在這裏綁定的 30 'click input[type=button]': 'doChange' 31 }, 32 doChange: function (event) { 33 //經過model發送數據到服務器 34 this.render('the5fire' + $("#search_input").val()); 35 } 36 }); 37 var searchView = new SearchView({ el: $("#search_container") }); 38 })(jQuery); 39 </script> 40 </html>
好了,知識回顧暫時到這裏,咱們要來咱們的東西了,否則搞不完了。
有點一頭霧水的感受,因而先上一張圖吧:
1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 <head> 3 <title></title> 4 </head> 5 <body> 6 <div id="contactapp"> 7 <header> 8 <h1> 9 通信錄</h1> 10 </header> 11 <section id="main"> 12 <ul id="contact-list"> 13 </ul> 14 </section> 15 <div class="create"> 16 <label> 17 姓名:<input type="text" id="name" /></label> 18 <label> 19 電話:<input type="text" id="phone" /></label> 20 <input type="button" value="保存" id="add" /> 21 </div> 22 </div> 23 </body> 24 </html>
下面的輸入框用以新建通信項目,contact-list用以顯示通信錄列表。整個頁面很是簡單,咱們先就完成這個功能便可。
完了咱們應該建立Contact模型了,咱們先來隨便寫寫代碼看看有神馬狀況發生:
var Contact = Backbone.Model.extend({ validate: function (attr) { if (!attr.name || attr.name.length > 5) { return '姓名格式錯誤'; } } }); var contact = new Contact(); var s = '';
這裏根據backbone的Model的extend方法創建了Contact模型。
其中可能會有驗證機制,我這裏隨便寫了一個,電話其實也須要驗證的。
而模型會有的方法,咱們暫時無論他了,先來個集合吧:
<script src="js/underscore.js" type="text/javascript"></script> <script src="js/backbone.js" type="text/javascript"></script> <script src="js/backbone.localStorage.js" type="text/javascript"></script> <script type="text/javascript"> var Contact = Backbone.Model.extend({ validate: function (attr) { if (!attr.name || attr.name.length > 5) { return '姓名格式錯誤'; } } }); var ContackList = Backbone.Collection.extend({ model: ContackList, localStorage: new Store('contacts')//全部信息保存至contacts空間下,注意這次用到了本地存儲的東西 }); var s = ''; </script>
這裏使用了本地存儲,因此咱們必須設置localStorage屬性。
如今咱們來設置視圖後:
1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 <head> 3 <title></title> 4 </head> 5 <body> 6 <div id="contactapp"> 7 <header> 8 <h1> 9 通信錄</h1> 10 </header> 11 <section id="main"> 12 <ul id="contact-list"> 13 </ul> 14 </section> 15 <div class="create"> 16 <label> 17 姓名:<input type="text" id="name" /></label> 18 <label> 19 電話:<input type="text" id="phone" /></label> 20 <input type="button" value="保存" id="add" /> 21 </div> 22 </div> 23 </body> 24 <script src="js/jquery.js" type="text/javascript"></script> 25 <script src="js/underscore.js" type="text/javascript"></script> 26 <script src="js/backbone.js" type="text/javascript"></script> 27 <script src="js/backbone.localStorage.js" type="text/javascript"></script> 28 <script type="text/javascript"> 29 (function ($) { 30 var Contact = Backbone.Model.extend({ 31 validate: function (attr) { 32 if (!attr.name || attr.name.length > 5) { 33 return '姓名格式錯誤'; 34 } 35 } 36 }); 37 38 var ContackList = Backbone.Collection.extend({ 39 model: ContackList, 40 localStorage: new Store('contacts'), //全部信息保存至contacts空間下,注意這次用到了本地存儲的東西 41 initialize: function (models, options) { 42 this.bind('add', options.view.add); 43 } 44 }); 45 var AppView = Backbone.View.extend({ 46 el: $('body'), 47 tmplate: _.template('<li><%= name %>:<%= phone %></li>'), 48 49 initialize: function () { 50 _.bindAll(this, 'save', 'add'); 51 this.contacts = new ContackList(null, { view: this }); 52 this.list = $('#contact-list'); 53 this.name = $('#name'); 54 this.phone = $('#phone'); 55 }, 56 events: { 57 'click #add': 'save' 58 }, 59 save: function () { 60 var model = new Contact({ name: this.name.val(), phone: this.phone.val() }); 61 this.contacts.add(model); 62 }, 63 add: function (model) { 64 var obj = model.toJSON(); 65 $(this.list).append(this.tmplate(obj)); 66 } 67 }); 68 var app = new AppView(); 69 70 })(jQuery); 71 </script> 72 </html>
咱們的簡單的界面終於出來了。。。。因而咱們來優化加功能吧:
1 <!DOCTYPE html> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <title></title> 5 </head> 6 <body> 7 <div id="contactapp"> 8 <header> 9 <h1> 10 通信錄</h1> 11 </header> 12 <section id="main"> 13 <ul id="contact-list"> 14 </ul> 15 </section> 16 <div class="create"> 17 <label> 18 姓名:<input type="text" id="name" /></label> 19 <label> 20 電話:<input type="text" id="phone" /></label> 21 <input type="button" value="保存" id="add" /> 22 </div> 23 </div> 24 </body> 25 <script src="js/jquery.js" type="text/javascript"></script> 26 <script src="js/underscore.js" type="text/javascript"></script> 27 <script src="js/backbone.js" type="text/javascript"></script> 28 <script src="js/backbone.localStorage.js" type="text/javascript"></script> 29 <script type="text/javascript"> 30 (function ($) { 31 var Contact = Backbone.Model.extend({ 32 initialize: function () { 33 this.bind("error", function (model, error) { 34 alert(error); 35 }); 36 }, 37 validate: function (attr) { 38 if (attr.name.length == '') { 39 return '姓名格式錯誤'; 40 } 41 } 42 }); 43 var ContactList = Backbone.Collection.extend({ 44 model: Contact, 45 localStorage: new Store('contacts') //全部信息保存至contacts空間下,注意這次用到了本地存儲的東西 46 47 }); 48 var list = new ContactList(); 49 var ContactView = Backbone.View.extend({ 50 tagName: 'li', 51 template: _.template('<div><%= name %>:<%= phone %></div>'), 52 events: { 53 'click li': 'test' 54 }, 55 initialize: function () { 56 _.bindAll(this, 'render', 'remove'); 57 this.model.bind('change', this.render); 58 this.model.bind('destroy', this.remove); 59 }, 60 render: function () { 61 var html = this.template(this.model.toJSON()); 62 //this.el是生成的空div 63 $(this.el).html(html); 64 //返回了當前視圖 65 return this; 66 }, 67 remove: function () { 68 $(this.el).remove(); 69 }, 70 test: function () { 71 alert(this); 72 var s = ''; 73 } 74 }); 75 var AppView = Backbone.View.extend({ 76 el: $('body'), 77 events: { 78 'click #add': 'save' 79 }, 80 initialize: function () { 81 this.name = this.$('#name'); 82 this.phone = this.$('#phone'); 83 this.list = this.$('#contact-list'); 84 85 _.bindAll(this, 'render', 'add', 'loadList', 'save'); 86 //爲集合綁定事件 87 list.bind('add', this.add); 88 //添加修改時觸發 89 list.bind('refresh', this.loadList); 90 list.fetch(); 91 }, 92 //添加項目 93 add: function (model) { 94 var view = new ContactView({ model: model }); 95 this.list.append(view.render().el); 96 // view.model.save({ name: model.name, phone: model.phone }); 97 var s = ''; 98 }, 99 loadList: function () { 100 list.each(this.add); 101 }, 102 save: function () { 103 var name = this.name.val(); 104 var phone = this.phone.val(); 105 list.create({ name: name, phone: phone }); 106 this.name.val(''); 107 this.phone.val(''); 108 } 109 }); 110 var app = new AppView(); 111 112 })(jQuery); 113 </script> 114 </html>
這個代碼與上述代碼有些不一樣,咱們來理一理:
① 模型與集合變化不大
② 具備2個視圖:
通信錄視圖,咱們後面通信錄會有編輯、刪除或者其餘功能,就在此上寫
全局視圖,AppView用於全局,可能還會顯示總體狀態。
③流程
由於咱們只有一個通信錄列表,因此將之全局化出來了:
var list = new ContactList();
ContactView主要關注自身,與總體能夠隔離開。
tagName指定了造成的dom的外層結構,不指定就是div
template會解析模板,我直接寫到這裏了,後面咱們作點修改給個刪除功能
template: _.template('<div><%= name %>:<%= phone %><a href="javascript:;">[刪除]</a></div>'),
events就是綁定的事件
PS:具體代碼各位本身看吧......
這裏將刪除事件加上就算階段完成了:
1 <!DOCTYPE html> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <title></title> 5 </head> 6 <body> 7 <div id="contactapp"> 8 <header> 9 <h1> 10 通信錄</h1> 11 </header> 12 <section id="main"> 13 <ul id="contact-list"> 14 </ul> 15 </section> 16 <div class="create"> 17 <label> 18 姓名:<input type="text" id="name" /></label> 19 <label> 20 電話:<input type="text" id="phone" /></label> 21 <input type="button" value="保存" id="add" /> 22 </div> 23 </div> 24 </body> 25 <script src="js/jquery.js" type="text/javascript"></script> 26 <script src="js/underscore.js" type="text/javascript"></script> 27 <script src="js/backbone.js" type="text/javascript"></script> 28 <script src="js/backbone.localStorage.js" type="text/javascript"></script> 29 <script type="text/javascript"> 30 (function ($) { 31 var Contact = Backbone.Model.extend({ 32 initialize: function () { 33 this.bind("error", function (model, error) { 34 alert(error); 35 }); 36 }, 37 validate: function (attr) { 38 if (attr.name.length == '') { 39 return '姓名格式錯誤'; 40 } 41 } 42 }); 43 var ContactList = Backbone.Collection.extend({ 44 model: Contact, 45 localStorage: new Store('contacts') //全部信息保存至contacts空間下,注意這次用到了本地存儲的東西 46 47 }); 48 var list = new ContactList(); 49 var ContactView = Backbone.View.extend({ 50 tagName: 'li', 51 template: _.template('<div><%= name %>:<%= phone %><a href="javascript:;" class="delete">[刪除]</a></div>'), 52 events: { 53 'click .delete': 'destroy' 54 }, 55 initialize: function () { 56 _.bindAll(this, 'render', 'remove'); 57 this.model.bind('change', this.render); 58 this.model.bind('destroy', this.remove); 59 }, 60 render: function () { 61 var html = this.template(this.model.toJSON()); 62 //this.el是生成的空div 63 $(this.el).html(html); 64 //返回了當前視圖 65 return this; 66 }, 67 destroy: function () { 68 this.model.destroy(); 69 }, 70 remove: function () { 71 $(this.el).remove(); 72 73 } 74 }); 75 var AppView = Backbone.View.extend({ 76 el: $('body'), 77 events: { 78 'click #add': 'save' 79 }, 80 initialize: function () { 81 this.name = this.$('#name'); 82 this.phone = this.$('#phone'); 83 this.list = this.$('#contact-list'); 84 85 _.bindAll(this, 'render', 'add', 'loadList', 'save'); 86 //爲集合綁定事件 87 list.bind('add', this.add); 88 //添加修改時觸發 89 list.bind('refresh', this.loadList); 90 list.fetch(); 91 }, 92 //添加項目 93 add: function (model) { 94 var view = new ContactView({ model: model }); 95 this.list.append(view.render().el); 96 // view.model.save({ name: model.name, phone: model.phone }); 97 var s = ''; 98 }, 99 loadList: function () { 100 list.each(this.add); 101 }, 102 save: function () { 103 var name = this.name.val(); 104 var phone = this.phone.val(); 105 list.create({ name: name, phone: phone }); 106 this.name.val(''); 107 this.phone.val(''); 108 } 109 }); 110 var app = new AppView(); 111 112 })(jQuery); 113 </script> 114 </html>
咱們又簡單的回顧了下backbone,此次學習後我和個人小夥伴表示都懂了。。。。
先上個圖:
尼瑪,一下多出了好多文件:
define(function () { var Contact = Backbone.Model.extend({ initialize: function () { this.bind("error", function (model, error) { alert(error); }); }, validate: function (attr) { if (attr.name.length == '') { return '姓名格式錯誤'; } } }); return Contact; });
define(['model/contact'], function (Contact) { var ContactList = Backbone.Collection.extend({ model: Contact, localStorage: new Store('contacts') //全部信息保存至contacts空間下,注意這次用到了本地存儲的東西 }); return ContactList; });
define(function () { var ContactView = Backbone.View.extend({ tagName: 'li', template: _.template('<div><%= name %>:<%= phone %><a href="javascript:;" class="delete">[刪除]</a></div>'), events: { 'click .delete': 'destroy' }, initialize: function () { _.bindAll(this, 'render', 'remove'); this.model.bind('change', this.render); this.model.bind('destroy', this.remove); }, render: function () { var html = this.template(this.model.toJSON()); //this.el是生成的空div $(this.el).html(html); //返回了當前視圖 return this; }, destroy: function () { this.model.destroy(); }, remove: function () { $(this.el).remove(); } }); return ContactView; });
define(['collection/contact', 'view/contact'], function (contact, ContactView) { window.list = new contact(); var AppView = Backbone.View.extend({ el: $('body'), events: { 'click #add': 'save' }, initialize: function () { this.name = this.$('#name'); this.phone = this.$('#phone'); this.list = this.$('#contact-list'); _.bindAll(this, 'render', 'add', 'loadList', 'save'); //爲集合綁定事件 list.bind('add', this.add); //添加修改時觸發 list.bind('refresh', this.loadList); list.fetch(); }, //添加項目 add: function (model) { var view = new ContactView({ model: model }); this.list.append(view.render().el); // view.model.save({ name: model.name, phone: model.phone }); var s = ''; }, loadList: function () { list.each(this.add); }, save: function () { var name = this.name.val(); var phone = this.phone.val(); list.create({ name: name, phone: phone }); this.name.val(''); this.phone.val(''); } }); return AppView; });
require.config({ paths: { jquery: 'js/jquery', underscore: 'js/underscore', backbone: 'js/backbone', bl: 'js/backbone.localStorage' } }); require(['jquery', 'underscore', 'backbone', 'bl', 'model/contact', 'collection/contact', 'view/contact', 'view/app'], function ($, _, b, bl, model, collection, view, app) { var app = new app(); });
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> </head> <body> <div id="contactapp"> <header> <h1> 通信錄</h1> </header> <section id="main"> <ul id="contact-list"> </ul> </section> <div class="create"> <label> 姓名:<input type="text" id="name" /></label> <label> 電話:<input type="text" id="phone" /></label> <input type="button" value="保存" id="add" /> </div> </div> </body> <script src="js/require.js" data-main="main" type="text/javascript"></script> </html>
因而,咱們功能完成了:
我和個人小夥伴說,尼瑪終於搞完了。。。。。。