上一章主要是通過簡單的代碼對Backbonejs做了一個概括的展示,這一章開始從Model層說起,詳細解釋Backbonejs中的Model這個東西。
對于Model這一部分,其官網是這么說的:“Model是js應用的核心,包括基礎的數據以及圍繞著這些數據的邏輯:數據轉換、驗證、屬性計算和訪問控制”。這句話基本上高度概括了Model在一個項目中的作用。實際上,不僅僅是js應用,在任何以數據收集和處理的項目中Model都是很重要的一塊內容。
Model這個概念在我的印象中是來自于MVC這個東西,Model在其中的作用,除了是對業務中實體對象的抽象,另外的作用就是做持久化,所謂持久化就是把數據存儲到磁盤上——文件形式、數據庫形式。在web端也有對應的操作,比如存入LocalStorage,或者Cookie。
在web端,Model還有一個重要的功能就是和服務器端進行數據交互,就像是服務器端的程序需要和數據庫交互一樣。因此Model應該是攜帶數據流竄于各個模塊之間的東西。
下面讓我們通過一個一個的實例來逐步了解Model。
先定義一個頁面結構,實踐時須在注釋的地方填上各小節的代碼
~~~
<!DOCTYPE html>
<html>
<head>
<title>the5fire-backbone-model</title>
</head>
<body>
</body>
<script src="http://the5fireblog.b0.upaiyun.com/staticfile/jquery-1.10.2.js"></script>
<script src="http://the5fireblog.b0.upaiyun.com/staticfile/underscore.js"></script>
<script src="http://the5fireblog.b0.upaiyun.com/staticfile/backbone.js"></script>
<script>
(function ($) {
/**
*此處填充代碼下面練習代碼
**/
})(jQuery);
</script>
</html>
~~~
## 2.1 最簡單的對象
~~~
var Man = Backbone.Model.extend({
initialize: function(){
alert('Hey, you create me!');
}
});
var man = new Man;
~~~
這個確實很簡單了,只是定義了一個最基礎的Model,只是實現了initialize這個初始化方法,也稱構造函數。這個函數會在Model被實例化時調用。
## 2.2 對象屬性賦值的兩種方法
第一種,直接定義,設置默認值。
~~~
var Man = Backbone.Model.extend({
initialize: function(){
alert('Hey, you create me!');
},
defaults: {
name:'張三',
age: '38'
}
});
var man = new Man;
alert(man.get('name'));
~~~
第二種,賦值時定義
~~~
var Man = Backbone.Model.extend({
initialize: function(){
alert('Hey, you create me!');
}
});
var man = new Man;
man.set({name:'the5fire',age:'10'});
alert(man.get('name'));
~~~
從這個對象的取值方式可以知道,屬性在一個Model是以字典(或者類似字典)的方式存在的,第一種設定默認值的方式,只不過是實現了Backbone的defaults這個方法,或者是給defaults進行了賦值。
## 2.3 對象中的方法
~~~
var 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());
~~~
也是比較簡單,只是增加了一個新的屬性,值是一個function。說到這,不知道你是否發現,在所有的定義或者賦值操作中,都是通過字典的方式來完成的,比如extend Backbone的Model,以及定義方法,定義默認值。方法的調用和其他的語言一樣,直接?`.`?即可,參數的定義和傳遞也一樣。
## 2.4 監聽對象中屬性的變化
假設你有在對象的某個屬性發生變化時去處理一些業務的話,下面的示例會有幫助。依然是定義那個類,不同的是我們在構造函數中綁定了name屬性的change事件。這樣當name發生變化時,就會觸發這個function。
~~~
var 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;
//觸發綁定的change事件,alert。
man.set({name:'the5fire'});
//觸發綁定的change事件,alert。
man.set({name:'the5fire.com'});
~~~
## 2.5 為對象添加驗證規則,以及錯誤提示
~~~
var Man = Backbone.Model.extend({
initialize: function(){
alert('Hey, you create me!');
//初始化時綁定監聽, change事件會先于validate發生
this.bind("change:name",function(){
var name = this.get("name");
alert("你改變了name屬性為:" + name);
});
this.bind("invalid",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.on('invalid', function(model, error){
// alert(error);
// });
//默認set時不進行驗證
man.set({name:''});
//手動觸發驗證, set時會觸發
//man.set({name:''}, {'validate':true});
//save時觸發驗證。根據驗證規則,彈出錯誤提示。
man.save();
~~~
## 2.6 和服務器進行交互,對象的保存和獲取
首先需要聲明的是,這個例子需要后端配合,可以在?[code](https://github.com/the5fire/backbonejs-learning-note/blob/master/code)?目錄中找到對應的py文件,需要webpy和mako這兩個庫。 這里需要為對象定義一個url屬性,調用save方法時會post對象的所有屬性到server端,調用fetch方法是又會發送get請求到server端。接受數據和發送數據均為json格式:
~~~
var Man = Backbone.Model.extend({
url:'/man/',
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'});
//會發送POST到模型對應的url,數據格式為json{"name":"the5fire","age":38}
man.save();
//然后接著就是從服務器端獲取數據使用方法fetch([options])
var man1 = new Man;
//第一種情況,如果直接使用fetch方法,
//那么他會發送get請求到你model的url中,
//你在服務器端可以通過判斷是get還是post來進行對應的操作。
man1.fetch();
//第二種情況,在fetch中加入參數,如下:
man1.fetch({url:'/man/'});
//這樣,就會發送get請求到/getmans/這個url中,
//服務器返回的結果樣式應該是對應的json格式數據,同save時POST過去的格式。
//不過接受服務器端返回的數據方法是這樣的:
man1.fetch({url:'/man/',
success:function(model,response){
alert('success');
//model為獲取到的數據
alert(model.get('name'));
},error:function(){
//當返回格式不正確或者是非json數據時,會執行此方法
alert('error');
}
});
~~~
還有一點值得一提的是關于url和urlRoot的事情了,如果你設置了url,那么你的CRUD都會發送對應請求到這個url上,但是這樣有一個問題,就是delete請求,發送了請求,但是卻沒有發送任何數據,那么你在服務器端就不知道應該刪除哪個對象(記錄),所以這里又一個urlRoot的概念,你設置了urlRoot之后,你發送PUT和DELETE請求的時候,其請求的url地址就是:/baseurl/[model.id],這樣你就可以在服務器端通過對url后面值的提取更新或者刪除對應的對象(記錄)
補充一點,就是關于服務器的異步操作都是通過Backbone.sync這個方法來完成的,調用這個方法的時候會自動的傳遞一個參數過去,根據參數向服務器端發送對應的請求。比如你save,backbone會判斷你的這個對象是不是新的,如果是新創建的則參數為create,如果是已存在的對象只是進行了改變,那么參數就為update,如果你調用fetch方法,那參數就是read,如果是destory,那么參數就是delete。也就是所謂的CRUD ("create", "read", "update", or "delete"),而這四種參數對應的請求類型為POST,GET,PUT,DELETE。你可以在服務器根據這個request類型,來做出相應的CRUD操作。
關于Backbone.sync在后面會有如何自定義這一部分的章節。
上面服務器端的代碼在?`code`?下可以找到,基于webpy和mako的。
- 關于
- 前言
- 第一章 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相關資源