講解JavaScript的Backbone.js框架的MVC結構設計理念
什么是Backbone.js?
Backbone.js是十大JS框架之首,Backbone.js 是一個重量級js MVC 應用框架,也是js MVC框架的鼻祖。它通過Models數(shù)據(jù)模型進行鍵值綁定及custom事件處理,通過模型集合器Collections提供一套豐富的API用于枚舉功能,通過視圖Views來進行事件處理及與現(xiàn)有的Application通過JSON接口進行交互。
簡而言之,Backbone是實現(xiàn)了web前端MVC模式的js庫
什么是MVC?
MVC:后端服務器首先(過程1)通過瀏覽器獲取頁面地址,對網(wǎng)址進行解析,得到視圖View給它的一個網(wǎng)址,然后通過控制器controller進行解析,然后去找對應的數(shù)據(jù)(過程2),找到數(shù)據(jù)后,再將數(shù)據(jù)Model返回給控制器(過程3),控制器controller再對數(shù)據(jù)進行加工,最后返回給視圖(過程4),即更新視圖View。這種結構在后端是非常清晰且易實現(xiàn)的

Backbone中MVC的機制
Backbone將數(shù)據(jù)呈現(xiàn)為模型, 你可以創(chuàng)建模型、對模型進行驗證和銷毀,甚至將它保存到服務器。 當UI的變化引起模型屬性改變時,模型會觸發(fā)"change"事件; 所有顯示模型數(shù)據(jù)的視圖會接收到該事件的通知,繼而視圖重新渲染。 你無需查找DOM來搜索指定id的元素去手動更新HTML。 — 當模型改變了,視圖便會自動變化?!俣劝倏?/p>
模式:一種解決問題的通用方法
—設計模式:工廠模式、適配器模式和觀察者模式
—框架模式:MVC、MVP、MVVM
控制器:通過控制器來連接視圖與模型。
MVC模式的思想:
就是把模型與視圖分離,通過控制器來連接他們
服務器端MVC模式非常容易實現(xiàn)
Model:模型即數(shù)據(jù),模型 是所有 js 應用程序的核心,包括交互數(shù)據(jù)及相關的大量邏輯: 轉換、驗證、計算屬性和訪問控制。你可以用特定的方法擴展 Backbone.Model
View:即你在頁面上所能看到的視圖。每一個單一的數(shù)據(jù)模型對應一個視圖View
web頁面本身就是一個很大的view,不太容易做到分離操作,backbone.js適合復雜的大型開發(fā),并為我們解決了這些難題
backbone的模塊
backbone有如下幾個模塊:
- Events:事件驅動模塊
- Model:數(shù)據(jù)模型
- Collection:模型集合器
- Router:路由器(對應hash值)
- History:開啟歷史管理
- Sync:同步服務器方式
- View:視圖(含事件行為和渲染頁面 相關方法)
集合器Collection是對單獨的數(shù)據(jù)模型進行統(tǒng)一控制
直接創(chuàng)建對象
Backbone依賴于Underscore.js, DOM 處理依賴于 Backbone.View 和 jQuery ,因此,在引入Backbone.js之前,Underscore.js必須在它之前引入,而jQuery也最好一并引入,最后再引入Backbone.js
<head lang="en"> <meta charset="UTF-8"> <title></title> <script src = "jquery-2.0.3.min.js"></script> <script src = "underscore-min.js"></script> <script src = "backbone.js"></script> </head> <body> var model = new Backbone.Model(); var col = new Backbone.Collection(); var view = new Backbone.View(); </body>
new后面是一個構造函數(shù),而Backbone是作為構造函數(shù)的命名空間來使用的
Model模塊
Backbone.Model.extend(properties, [classProperties])
Backbone通過extend來擴展實例方法和靜態(tài)方法:
<script type="text/javascript">
//extend接收的第一個參數(shù)是json格式的字符串,用來擴展實例方法
//第二個參數(shù)也是json格式的字符串,用來擴展靜態(tài)方法
var M = Backbone.Model.extend({
abc : function(){ //實例方法
alert("hello backbone");
}
},{
def : function(){ //靜態(tài)方法
alert("hi");
}
});
var model = new M;
model.abc();//實例方法要用實例對象來訪問
M.def();//靜態(tài)方法直接掛載到了構造函數(shù)上,可以通過構造函數(shù)來直接訪問
</script>
靜態(tài)方法其實就是多了一個命名空間。以上是給構造函數(shù)添加實例方法和靜態(tài)方法
var M = Backbone.Model.extend({})
通過extend來為模型的構造函數(shù)擴展方法,M就是擴展之后的構造函數(shù)
繼承
<script type="text/javascript">
//繼承
var Mod = backbone.Model.extend({
abc : function(){
alert(123);
}
});
var ChildMod = Mod.extend();
var model = new ChildMod;
model.abc();//子類繼承了父類的方法
</script>
Backbone源碼結構

1: (function() {
2: Backbone.Events // 自定義事件
3: Backbone.Model // 模型構造函數(shù)和原型擴展
4: Backbone.Collection // 集合構造函數(shù)和原型擴展
5: Backbone.Router // 路由配置器構造函數(shù)和原型擴展
6: Backbone.History // 路由器構造函數(shù)和原型擴展
7: Backbone.View // 視圖構造函數(shù)和原型擴展
8: Backbone.sync // 異步請求工具方法
9: var extend = function (protoProps, classProps) { ... } // 自擴展函數(shù)
10: Backbone.Model.extend = Backbone.Collection.extend = Backbone.Router.extend = Backbone.View.extend = extend; // 自擴展方法
11: }).call(this);
JS MVC職責劃分
M 模型
業(yè)務模型:業(yè)務邏輯、流程、狀態(tài)、規(guī)則
(核心)數(shù)據(jù)模型:業(yè)務數(shù)據(jù)、數(shù)據(jù)校驗、增刪改查(AJAX)
V 視圖
(核心)視圖:定義、管理、配置
模板:定義、配置、管理
組件:定義、配置、管理
(核心)用戶事件配置、管理
用戶輸入校驗、配置、管理
C 控制器/分發(fā)器
(核心)事件分發(fā)、模型分發(fā)、視圖分發(fā)
不做數(shù)據(jù)處理、業(yè)務處理,即業(yè)務無關
擴展:權限控制、異常處理等
C是JSMVC框架的核心,實現(xiàn)集中式配置和管理,可以有多個控制器
工具庫
主要是異步請求、DOM操作,可以依賴于jQuery等
Model指的是一條一條的數(shù)據(jù),而集合Collection指的是對Model中的多條數(shù)據(jù)進行管理。
模型 Model
我們用Backbone.Model表示應用中所有數(shù)據(jù),models中的數(shù)據(jù)可以創(chuàng)建、校驗、銷毀和保存到服務端。
對象賦值的方法
1、直接定義,設置默認值
Trigkit = Backbone.Model.extend({
initialize : function () {
alert('hi!');
},
defaults:{
age : '22',
profession : 'coder'
}
});
var coder = new Trigkit;
alert(coder.get('age'));//22
2、 賦值時定義
<script type="text/javascript">
Trigkit = Backbone.Model.extend({
initialize : function () {
alert('hi!');
}
});
var t = new Trigkit;
t.set({name :'huang',age : '10'});
alert(t.get('name'));
</script>
對象中的方法
<script type="text/javascript" src="Underscore.js"></script>
<script type="text/javascript" src="backbone-1.1.2.js"></script>
<script type="text/javascript">
var Trigkit4 = Backbone.Model.extend({
initialize : function () {
alert("hello world!");
},
defaults : {
name : 'zhangsan',
age : 21
},
aboutMe: function () {
return '我叫' + this.get('name') + ',今年' + this.get('age') + '歲';
}
});
var t = new Trigkit4;
alert(t.aboutMe());
</script>
當模型實例化時,他的initialize方法可以接受任意實例參數(shù),其工作原理是backbone模型本身就是構造函數(shù),所以可以使用new生成實例:
var User = Backbone.Model.extend({
initialize: function (name) {
this.set({name: name});
}
});
var user = new User('trigkit4');
alert(user.get('name'), 'trigkit4');//trigkit4
看下backbone的源碼:
var Model = Backbone.Model = function(attributes, options) {
var attrs = attributes || {};
options || (options = {});
this.cid = _.uniqueId('c');
this.attributes = {};
if (options.collection) this.collection = options.collection;
if (options.parse) attrs = this.parse(attrs, options) || {};
attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
this.set(attrs, options);
this.changed = {};
this.initialize.apply(this, arguments);
};
initialize: function(){},//initialize是默認的空函數(shù)
Model 的事件綁定
為了能及時更新view,我們需要通過事件綁定機制來處理和響應用戶事件:
<script type="text/javascript">
var Task = Backbone.Model.extend({
initialize: function () {
this.on("change:name", function (model) {
alert("my name is : " + model.get("name"));
});
}
});
var task = new Task({ name:"oldname", state:"working"});
task.set({name:"trigkit"});
// object.on(event, callback, [context])
</script>
</head>
關于事件綁定,有on,off,trigger,once,listenTo,stopListening,listenToOnce等方法,具體參照:http://documentcloud.github.io/backbone/#Events

集合 Collection
Backbone.Collection就是一個Model對象的有序集合。因為Model是一條數(shù)據(jù)記錄,也就是說,Collection相當于是一個數(shù)據(jù)集。具有增加元素,刪除元素,獲取長度,排序,比較等一系列工具方法,說白了就是一個保存models的集合類。
<script type="text/javascript">
var Book = Backbone.Model.extend({
defaults : {
title:'default'
},
initialize: function(){
alert('hello backbone!');//彈出3次
}
});
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]); //注意這里面是數(shù)組,或者使用add
var bookShelf = new BookShelf;
bookShelf.add(book1);
bookShelf.add(book2);
bookShelf.add(book3);
bookShelf.remove(book3);
//基于underscore這個js庫,還可以使用each的方法獲取collection中的數(shù)據(jù)
bookShelf.each(function(book){
alert(book.get('title'));
});
</script>
collection.model覆蓋此屬性來指定集合中包含的模型類。可以傳入原始屬性對象(和數(shù)組)來 add, create,和 reset,傳入的屬性會被自動轉換為適合的模型類型。

視圖 View
Backbone.View中可以綁定dom元素和客戶端事件。頁面中的html就是通過views的render方法渲染出來的,當新建一個view的時候通過要傳進一個model作為數(shù)據(jù)
view.$el:一個視圖元素的緩存jQuery對象。 一個簡單的引用,而不是重新包裝的DOM元素。
一個簡單的View:
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript" src="jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="Underscore.js"></script>
<script type="text/javascript" src="backbone-1.1.2.js"></script>
<script type="text/javascript">
var TestView = Backbone.View.extend({ //創(chuàng)建一個view,其實就是一個HTML的DOM節(jié)點
initialize: function() {
this.render();
},
render: function() { // 渲染方法
this.$el.html('Hello World'); //this.el就是HTML節(jié)點,通過jQuery的html方法填充內(nèi)容
return this;
}
});
$(function () {
var test = new TestView({el: $('#body')});// 以目標節(jié)點為el參數(shù),創(chuàng)建一個view的實例,render函數(shù)將會被自動調用并將渲染結果填充到el中
//test.render(); // 如果沒在 initialize 里調用 render 的話,就需要在這里調用一次
});
</script>
</head>
<body>
<div id="body"></div>
</body>
elview.el所有的視圖都擁有一個 DOM 元素(el 屬性),即使該元素仍未插入頁面中去。 視圖可以在任何時候渲染,然后一次性插入 DOM 中去,這樣能盡量減少 reflows 和 repaints 從而獲得高性能的 UI 渲染。 this.el 可以從視圖的 tagName, className, id 和 attributes 創(chuàng)建,如果都未指定,el 會是一個空 div。 --官網(wǎng)

擴展方法 extend
模型、集合、視圖、路由器都有一個extend方法,用于擴展原型屬性和靜態(tài)屬性,創(chuàng)建自定義的模型、集合、視圖、路由器類。
Backbone.Model.extend Backbone.Model.extend(properties, [classProperties])
要創(chuàng)建自己的 Model 類,你可以擴展 Backbone.Model 并提供實例 properties(屬性) , 以及可選的可以直接注冊到構造函數(shù)的classProperties(類屬性)。
Backbone.View.extend Backbone.View.extend(properties, [classProperties])
開始創(chuàng)建自定義的視圖類。 通常我們需要重載 render 函數(shù),聲明 events, 以及通過 tagName, className, 或 id 為視圖指定根元素。 Backbone.View通過綁定視圖的 render 函數(shù)到模型的 "change" 事件 — 模型數(shù)據(jù)會即時的顯示在 UI 中。
Backbone.Collection.extend Backbone.Collection.extend(properties, [classProperties])
通過擴展 Backbone.Collection 創(chuàng)建一個 Collection 類。實例屬性參數(shù) properties 以及 類屬性參數(shù) classProperties 會被直接注冊到集合的構造函數(shù)。
Backbone.Router.extend Backbone.Router.extend(properties, [classProperties])
開始創(chuàng)建一個自定義的路由類。當匹配了 URL 片段便執(zhí)行定義的動作,并可以通過 routes 定義路由動作鍵值對。
Router與controller
controller是Backbone 0.5以前的叫法,現(xiàn)在改名叫Router了。
Backbone.Router 為客戶端路由提供了許多方法,并能連接到指定的動作(actions)和事件(events)。
頁面加載期間,當應用已經(jīng)創(chuàng)建了所有的路由,需要調用 Backbone.history.start()
查看下面示例:
<script type="text/javascript">
var AppRouter = Backbone.Router.extend({
routes: {
"index" : "index",
"task/:id": "task",
"*acts": "tasklist"
},
index: function() {
alert("index");
},
tasklist: function(action) {
alert(action);
},
task: function(id) {
alert(id);
}
});
var app = new AppRouter;
Backbone.history.start();
</script>
在瀏覽器里打開頁面后,在url的html后面依次加上:
#/index #/task/1 #/test/xxxx
將分別彈出出:index, 1, test/xxxx
這就是Router的功能。
- Extjs4.1.x 框架搭建 采用Application動態(tài)按需加載MVC各模塊完美實現(xiàn)
- Javascript MVC框架Backbone.js詳解
- 前端輕量級MVC框架CanJS詳解
- 超級簡單實現(xiàn)JavaScript MVC 樣式框架
- 12種JavaScript常用的MVC框架比較分析
- 使用jQuery.form.js/springmvc框架實現(xiàn)文件上傳功能
- Angularjs中的事件廣播 —全面解析$broadcast,$emit,$on
- AngularJs解決跨域問題案例詳解(簡單方法)
- jquery.form.js框架實現(xiàn)文件上傳功能案例解析(springmvc)
- indexedDB bootstrap angularjs之 MVC DOMO (應用示例)
- AngularJs Javascript MVC 框架
相關文章
全面解析JavaScript的Backbone.js框架中的Router路由
這篇文章主要介紹了Backbone.js框架中的Router路由功能,Router在Backbone中相當于一個MVC框架中的Controller控制器功能,需要的朋友可以參考下2016-05-05
JavaScript的Backbone.js框架入門學習指引
這篇文章主要介紹了JavaScript的Backbone.js框架入門學習指引, 其中特別講到了Backbone中的關鍵部分Router路由器,需要的朋友可以參考下2016-05-05
JavaScript的Backbone.js框架的一些使用建議整理
這篇文章主要介紹了JavaScript的Backbone.js框架的一些使用建議整理,文中列的幾點主要還是針對DOM方面的操作,需要的朋友可以參考下2016-02-02
深入解析JavaScript框架Backbone.js中的事件機制
這篇文章主要介紹了JavaScript框架Backbone.js中的事件機制,其中涉及到Backbone的MVC結構及內(nèi)存使用方面的很多知識,需要的朋友可以參考下2016-02-02
詳解Backbone.js框架中的模型Model與其集合collection
這篇文章主要介紹了Backbone.js框架中的模型Model與其集合collection,Backbone擁有與傳統(tǒng)MVC框架相類似的Model與View結構,需要的朋友可以參考下2016-05-05
簡單了解Backbone.js的Model模型以及View視圖的源碼
這篇文章主要簡單介紹了Backbone.js的Model模型以及View視圖的源碼,Backbone是一款高人氣JavaScript的MVC框架,需要的朋友可以參考下2016-02-02

