這里說的定制Backbonejs,主要是定制Backbone中的sync部分,也就是最后和服務器端通信的部分。
## 17.1 三個級別的定制
首先得說,在Backbone里面和后端能通信的對象也就兩個——Model和Collection。這倆的主要工作就是從服務器拉取數據,保存到實例中,或者把實例中的屬性發送到服務器端。
上面兩中類型的對象都是基于Backbone.sync來進行通信的,同時也可以定義各自的sync方法,類似這樣:
_Model級別的_
~~~
var Message = Backbone.Model.extend({
urlRoot: '/message',
// 這么寫, 打印要操作的實體, 調用系統的sync
sync: function(method, model, options){
console.log(model);
return Backbone.sync(method, model, options);
},
});
~~~
_Collection級別的_
~~~
var Messages = Backbone.Collection.extend({
url: '/message',
model: Message,
// 這么寫, 打印要操作的實體, 調用系統的sync
sync: function(method, collection, options){
console.log(collection);
return Backbone.sync(method, collection, options);
},
});
~~~
當然,也會存在這樣的需求,要修改全局的sync:
~~~
var old_sync = Backbone.sync;
Backbone.sync = function(method, model, options) {
console.log(model);
return old_sync(method, model, options);
}
~~~
所謂定制,是Backbonejs給開發者提供的可以被重寫的接口。因此定制過程也得符合Backbone對sync的定義。
## 17.2 簡單實例,用socketio通信
在?[wechat](https://github.com/the5fire/wechat)?這個項目中為了保證聊天的實時性,我引入了socketio,后端使用gevent-socketio,(socketio這個東西不打算寫,和主題關系不大,有需求的可以題issue)。
實時聊天的需求主要是在Message上,用戶A發送一個請求,在同一聊天室內的其他用戶應該立馬能看見。之前有兩個版本:
* 第一版是發送message時會調用messages的fetch方法,也就是用戶只有發言才能看到別人發的聊天內容,代碼如下:
~~~
message.save(null, {
success: function(model, response, options){
comment_box.val('');
// 重新獲取,看服務器端是否有更新
// 比較丑陋的更新機制
messages.fetch({
data: {topic_id: topic_id},
success: function(){
self.message_list.scrollTop(self.message_list_div.scrollHeight);
messages.add(response);
},
});
},
});
~~~
* 第二版是引入socketio之后,在save完數據之后,通過socket把數據再次發送到服務器上的socket端,服務器再挨個發送數據到各個客戶端,代碼如下:
~~~
message.save(null, {
success: function(model, response, options){
comment_box.val('');
messages.add(response);
// 發送成功之后,通過socket再次發送
// FIXME: 最后可通過socket直接通信并保存
socket.emit('message', response);
},
});
// 對應著有一個socket監聽, 監聽服務器發來的消息
// 監聽message事件,添加對話到messages中
socket.on('message', function(response) {
messages.add(response);
});
~~~
可以看得出來,上面的第二版算是比較合適了,但是還是有些別扭,數據要重復發送。因此終于到了需要定制的時刻了。
上面說了,有三種級別的定制。根據我的需求,只需要定制Model級別的就可以了,怎么定制呢?
和一開頭的示例代碼類似:
~~~
var Message = Backbone.Model.extend({
urlRoot: '/message',
sync: function(method, model, options){
if (method === 'create') {
socket.emit('message', model.attributes);
$('#comment').val('');
} else {
return Backbone.sync(method, model, options);
};
},
});
// 對應著上面的那個message.save后的一堆東西都可以去掉了,直接
message.save();
~~~
這樣就好了,客戶端只需要發送一次數據。但要記得在服務器端的監聽message的接口上添加保存message的邏輯。
好了,定制就介紹這么多。關于上面提到的代碼想了解上下文的,可以到我的wechat這個項目的master分支查看。
- 關于
- 前言
- 第一章 Hello Backbonejs
- 第二章 Backbonejs中的Model實踐
- 第三章 Backbonejs中的Collections實踐
- 第四章 Backbonejs中的Router實踐
- 第五章 Backbonejs中的View實踐
- 第六章 實戰演練:todos分析(一)
- 第七章 實戰演練:todos分析(二)View的應用
- 第八章 實戰演練:todos分析(三)總結
- 第九章 后端環境搭建:web.py的使用
- 第十章 實戰演練:擴展todos到Server端(backbonejs+webpy)
- 第十一章 前后端實戰演練:Web聊天室-功能分析
- 第十二章 前后端實戰演練:Web聊天室-詳細設計
- 第十三章 前后端實戰演練:Web聊天室-服務器端開發
- 第十四章 前后端實戰演練:Web聊天室-前端開發
- 第十五章 引入requirejs
- 第十六章 補充異常處理
- 第十七章 定制Backbonejs
- 第十八章 再次總結的說
- Backbonejs相關資源