Model
關於backbone,最基礎的一個東西就是model,這個東西就像是後端開發中的資料庫映射那個model一樣,也是資料物件的模型,並且應該是和後端的model有相同的屬性(僅是需要透過前端來操作的屬性)。
下面就從實例來一步一步的帶大家來了解backbone的model到底是什麼樣的一個東西。
先定義一個html的頁面:
<!DOCTYPE html> <html> <head> <title>the5fire-backbone-model</title> </head> <body> </body> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script> <script src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.4/underscore-min.js"></script> <script src="http://ajax.cdnjs.com/ajax/libs/backbone.js/0.3.3/backbone-min.js"></script> <script> (function ($) { /** *此处填充代码 **/ })(jQuery); </script> </html>
下面的程式碼需要填到這個html的script標籤中的function。
1、最簡單的一個物件
Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); } }); var man = new Man;
這個就很簡單了,在helloworld裡面也有了一個model的展現,不定義了屬性,這裡是一個 初始化時的方法,或者稱之為構造函數。
2、物件賦值的兩種方法
第一種,直接定義,設定預設值。
Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); }, defaults: { name:'张三', age: '38' } }); var man = new Man; alert(man.get('name'));
第二種,賦值時定義
Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); } }); man.set({name:'the5fire',age:'10'}); alert(man.get('name'));
取值的時候都是用get。
3、物件中的方法
Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); }, defaults: { name:'张三', age: '38' }, aboutMe: function(){ return '我叫' + this.get('name') + ',今年' + this.get('age') + '岁'; } }); var man = new Man; alert(man.aboutMe());
4、監聽物件中屬性的變化
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。
5、為物件新增驗證規則,以及錯誤提示
Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); //初始化时绑定监听 this.bind("change:name",function(){ var name = this.get("name"); alert("你改变了name属性为:" + name); }); this.bind("error",function(model,error){ alert(error); }); }, defaults: { name:'张三', age: '38' }, validate:function(attributes){ if(attributes.name == '') { return "name不能为空!"; } }, aboutMe: function(){ return '我叫' + this.get('name') + ',今年' + this.get('age') + '岁'; } }); var man = new Man; man.set({name:''}); //根据验证规则,弹出错误提示。
6、物件的取得與保存,需要伺服器端支援才能測試。
首先需要為物件定義一個url屬性,呼叫save方法時會post物件的所有屬性到server端。
Man = Backbone.Model.extend({ url:'/save/', initialize: function(){ alert('Hey, you create me!'); //初始化时绑定监听 this.bind("change:name",function(){ var name = this.get("name"); alert("你改变了name属性为:" + name); }); this.bind("error",function(model,error){ alert(error); }); }, defaults: { name:'张三', age: '38' }, validate:function(attributes){ if(attributes.name == '') { return "name不能为空!"; } }, aboutMe: function(){ return '我叫' + this.get('name') + ',今年' + this.get('age') + '岁'; } }); var man = new Man;; man.set({name:'the5fire'}); man.save(); //会发送POST到模型对应的url,数据格式为json{"name":"the5fire","age":38} //然后接着就是从服务器端获取数据使用方法fetch([options]) var man1 = new Man; //第一种情况,如果直接使用fetch方法,那么他会发送get请求到你model的url中, //你在服务器端可以通过判断是get还是post来进行对应的操作。 man1.fetch(); //第二种情况,在fetch中加入参数,如下: man1.fetch({url:'/getmans/'}); //这样,就会发送get请求到/getmans/这个url中, //服务器返回的结果样式应该是对应的json格式数据,同save时POST过去的格式。 //不过接受服务器端返回的数据方法是这样的: man1.fetch({url:'/getmans/',success:function(model,response){ alert('success'); //model为获取到的数据 alert(model.get('name')); },error:function(){ //当返回格式不正确或者是非json数据时,会执行此方法 alert('error'); }});
註:上述程式碼僅皆為可正常執行的程式碼,不過關於伺服器端的實例在後面會有。
這裡還要補充一點,就是關於伺服器的非同步操作都是透過Backbone.sync這個方法來完成的,呼叫這個方法的時候會自動的傳遞一個參數過去,根據參數向伺服器端發送對應的請求。例如你save,backbone會判斷你的這個物件是不是新的,如果是新建立的則參數為create,如果是已存在的物件只是進行了改變,那麼參數就為update,如果你呼叫fetch方法,那參數就是read,如果是destory,那麼參數就是delete。也就是所謂的CRUD ("create", "read", "update", or "delete"),而這四種參數對應的請求類型為POST,GET,PUT,DELETE。你可以在伺服器根據這個request類型,來做出對應的CRUD操作。
Note:
關於url和urlRoot的事,如果你設定了url,那麼你的CRUD都會發送對應請求到這個url上,但是這樣又一個問題,就是delete請求,發送了請求,但是卻沒有發送任何數據,那麼你在伺服器端就不知道應該刪除哪個物件(記錄),所以這裡又一個urlRoot的概念,你設定了urlRoot之後,你發送PUT和DELETE請求的時候,其請求的url位址就是:/baseurl/[model.id ],這樣你就可以在伺服器端透過對url後面值的提取更新或刪除對應的物件(記錄)。
Collection
collection是model物件的一個有序的集合,概念理解起來十分簡單,在透過幾個例子來看一下,會覺得更簡單。
1、關於book和bookshelf的例子
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')); });
很簡單,不解釋
2、使用fetch從伺服器端取得資料
首先要在上面的的Bookshelf定義url,注意collection中並沒有urlRoot這個屬性。或是你直接在fetch方法中定義url的值,如下:
bookShelf.fetch({url:'/getbooks/',success:function(collection,response){ collection.each(function(book){ alert(book.get('title')); }); },error:function(){ alert('error'); }});
其中也定義了兩個接受返回值的方法,具體含義我想很容易理解,返回正確格式的數據,就會調用success方法,錯誤格式的數據就會調用error方法,當然error方法也看加入和success方法一樣的形參。
對應的BookShelf的回傳格式如下:[{'title':'book1'},{'title':'book2'}.....]
3、reset方法
這個方法的時候是要跟上面的fetch進行配合的,collection在fetch到資料之後,會呼叫reset方法,所以你需要在collection中定義reset方法或是綁定reset方法。這裡使用綁定示範:
bookShelf.bind('reset',showAllBooks); showAllBooks = function(){ bookShelf.each(function(book){ ​//将book数据渲染到页面。 }); }
綁定的步驟要在fetch之前進行。
以下給出關於collection的完整程式碼,需要伺服器端支援才行,伺服器端的搭建在後面會寫到。
<!DOCTYPE html> <html> <head> <title>the5fire-backbone-collection</title> </head> <body> </body> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script> <script src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.4/underscore-min.js"></script> <script src="http://ajax.cdnjs.com/ajax/libs/backbone.js/0.3.3/backbone-min.js"></script> <script> (function ($) { //collection是一个简单的models的有序集合 //1、一个简单的例子 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); /* for(var i=0; i<bookShelf.models.length; i++) { alert(bookShelf.models[i].get('title')); } */ //基于underscore这个js库,还可以使用each的方法获取collection中的数据 bookShelf.each(function(book){ alert(book.get('title')); }); //2、使用fetch从服务器端获取数据,使用reset渲染 bookShelf.bind('reset', showAllBooks); bookShelf.fetch({url:'/getbooks/',success:function(collection,response){ collection.each(function(book){ alert(book.get('title')); }); },error:function(){ alert('error'); }}); showAllBooks = function(){ bookShelf.each(function(book){ ​//将book数据渲染到页面。 }); } //上述代码仅仅均为可正常执行的代码,不过关于服务器端的实例在后面会有。 })(jQuery); </script> </html>