Model和Collection和后台的WEB server進行數據同步非常方便, 都只需要在實行里面添加一url就可以了,backbone會在model進行save或者collection進行create時,自動將數據用POST或者PUT方式通過該url發送到后端。按照POST和PUT的含義,backbone采用的原則是: 如果model數據為一個全新的實例,則使用POST請求;如果model數據是一個已經存在的實例, 單需要修改實例屬性,則采用PUT請求。
所以,問題的關鍵是,backbone判斷實例數據是新舊的依據是什么? backbone采用了以下幾種約定:
1. 如下的Model類User,由於不存在鍵值屬性,那么就認為是新實例對象,在save或者create時,就用POST請求。
var User = Backbone.Model.extend({ initialize: function(user) { }, defaults: { uid: "", name: "" }, url:"/users/", }); var UserList = Backbone.Collection.extend({ url: "/users", load: function() { } }); var userList = new UserList(User) var userList.create({uid: "a", name:"Peter"}); //通create在userList中新建一個user並發送POST請iutongbu var bill = new User({uid: "b", name:"Bill"}); //只在JS端創建了Model。單還沒同步到后端 bill.save(); //save觸發POST請求同步
userList.add(bill); //只是將JS的bill實例加入userList,不觸發HTTP請求
2. 如下的Model類User,uid被定義為鍵值屬性,創建實例時, uid為空,那么也是新實例對象,在save或者create時,就用POST請求。
var User = Backbone.Model.extend({ initialize: function(user) { }, defaults: { uid: "", name: "" }, idAttribute:"uid", //uid被定義為鍵值屬性 url:"/users/", }); var UserList = Backbone.Collection.extend({ url: "/users", load: function() { } }); var userList = new UserList(User) var userList.create({name: "Peter"}); //鍵值uid未設值, backbone認為是新實例,所以通create在userList中新建一個user並發送POST請求同步 var bill = new User({name: "Bill"}); bill.save(); //鍵值uid未設值, backbone認為是新數據, 所以, save也觸發POST請求同步
3. 如下的Model類User,uid被定義為鍵值屬性,創建實例時, uid不為空,在save或者create時,就用PUT請求。
var User = Backbone.Model.extend({ initialize: function(user) { }, defaults: { uid: "", name: "" }, idAttribute:"uid", //uid被定義為鍵值屬性 url:"/users/", }); var UserList = Backbone.Collection.extend({ url: "/users", load: function() { } }); var userList.create({uid: "a", name:"Peter"}); //由於存在鍵值uid, 所以通create在userList中新建一個user並發送PUT請求同步 var bill = new User({uid: "b", name:"Bill"}); //只在JS端創建了Model。單還沒同步到后端 bill.save(); //由於存在鍵值uid, 所以, save也觸發PUT請求同步
4. Backbone中,鍵屬性除了用顯示的idAttribute定義以外,還有一個隱式的約定,即如果model的屬性里面有個"id", 那么這個"id"屬性就是鍵屬性。所以以下定義的User雖然沒有顯示定義鍵屬性,但卻是有鍵值的,所以同步后台時會發送PUT請求
var User = Backbone.Model.extend({ initialize: function(user) { }, defaults: { id: "", name: "" }, url:"/users/", }); var UserList = Backbone.Collection.extend({ url: "/users", load: function() { } }); var userList = new UserList(User) var userList.create({id: "a", "Peter"}); //由於存在鍵值id, 所以通create在userList中新建一個user並發送PUT請求同步 var bill = new User({id: "b", "Bill"}); //只在JS端創建了Model。單還沒同步到后端 bill.save(); //由於存在鍵值id, 所以, save也觸發PUT請求同步
5. 以上任何一種約定,backbone內部的判斷邏輯其實都在isNew()方法中, isNew()是Model內部的一個方法, 返回值為true,表示為新實例,save/create觸發POST請求; 返回值為false, save/create觸發PUT請求。如下,雖然設有隱式的id鍵屬性,單由於重載后的isNew()方法始終返回true, 所以依然觸發POST請求
var User = Backbone.Model.extend({ initialize: function(user) { }, defaults: { id: "", name: "" }, url:"/users/", isNew:function() { return true; } }); var UserList = Backbone.Collection.extend({ url: "/users", load: function() { } }); var userList = new UserList(User) var userList.create({id: "a", name:"Peter"}); //由於isNew()返回值為true, 所以通create在userList中新建一個user並發送POST請求同步 var bill = new User({id: "b", name:"Bill"}); bill.save(); //由於isNew()返回值為true所以, save也觸發POST請求同步
另外需要注意的是,發送PUT時, URL請求后面會自動加上鍵值,變成“/users/a”,由於沒有鍵值,所以POST實際發送的url和定義時一樣