**樂帝當年學習backbone時,最開始是看官網todoMVC的實現,后來了解到requireJS便于管理JS代碼,就對官網代碼做了requireJS管理。但此時樂帝感覺此時的todoMVC仍然不夠簡明,為了加深對MVC架構的理解,樂帝對原有appview代碼進行了重構,將相關顯示模塊單獨提取出自稱view,實現view原子化。樂帝已經將這個項目上傳([下載地址](http://download.csdn.net/detail/yingyiledi/8025387))。**
**加入requireJS的目錄結構:**
****
**這里主要用到templates用于放置view對應的模板,views則對應backbone中view文件。如果說backbone是前端MVC,那么model是對數據建立模型,collection則是對model統一管理,view則起到控制器的作用,用于填充數據到模板,并渲染模板到顯示。model、collection起到M作用,view起到C的作用,模板則起到V的作用。**
**然后我們看一下todoMVC的效果圖:**
****
**從最終效果圖,我們可以分析出,要對原有appview中解耦出原子view,就需要判斷出哪些是原子view,原子view需要具備兩點:**
- **具有動態交互效果**
- **與其他頁面部分獨立**
**當然這里的原子view定義還值得商榷,樂帝根據以上兩個原則對view進行了重新劃分。**
**且看views目錄結構:**
****
**對應模板目錄結構:**
****
**需要注意的是,這里appview并沒有對應的模板,而是通過設置el: "#todoapp",在index.html文件中,統一對原子view進行管理。**
**下面以ToggleAllView類源代碼為例子,我們分析下,原子view職能的組成:**
~~~
define([
'jquery',
'underscore',
'backbone',
'text!templates/toggleAll.html'
], function($, _, Backbone, toggleTemplate) {
var ToggleAllView = Backbone.View.extend({
toggleTemplate: _.template(toggleTemplate),
events: {
"click #toggle-all": "toggleAllComplete"
},
initialize: function() {
this.listenTo(this.collection, "all", this.render); //除了todoview與todomodel一一對應
// 其他相關操作都會監聽collection
},
render: function() {
this.$el.html(this.toggleTemplate());
var done = this.collection.done().length;
var remaining = this.collection.remaining().length;
this.allCheckbox = this.$("#toggle-all")[0];
this.allCheckbox.checked = !remaining;
return this;
},
toggleAllComplete: function() {
var done = this.allCheckbox.checked;
this.collection.each(function(todo) {
todo.save({
done: done
});
}); //這里通過判斷單選框是否選中,修改所有modeldone屬性
}
});
return ToggleAllView;
});
~~~
**上述代碼中職能主要有如下幾種:**
- **設置el或tagname,用于定義在上一層view放置的位置,或包裹的標簽**
- **設置對應模板(Template)**
- **定義交互事件,并連帶定義交互函數**
- **初始化函數(initialize),一般設置對collection或者model的監聽,用于view之間的通信**
- **渲染函數(render),用于渲染數據到模板中,設置其他一些全局函數**
**由此可見,原子view將職能劃分的很清楚,這也是前端MVC架構的原因,而不是之前純腳本時代,代碼間高度耦合,牽一發而動全身。**
**對于學習backbone,原子view和appview各自代碼都不難理解,難于理解或者它精妙之處,在于對事件的監聽機制,正是這種機制,處理了view之間的通信,從而將松散的view拼裝成性能優良的整理。**
**todoView的監聽:**
~~~
initialize: function() {
this.listenTo(this.model, "change", this.render);
this.listenTo(this.model, "destroy", this.remove); //當模型被刪除,視圖相應被移除
}
~~~
**這里對每個todoview進行與之綁定的model數據監聽,修改,則重新渲染;銷毀,則移除此todoview。**
**再看ToggleAllView的監聽:**
~~~
initialize: function() {
this.listenTo(this.collection, "all", this.render); //除了todoview與todomodel一一對應
// 其他相關操作都會監聽collection
}
~~~
**這個監聽更“狠”,只要collection有變動,就會重新渲染,以達到實時交互的效果。**
**那么appview是如何管理各個子view的呢?**
**且看兩個appview函數:**
~~~
initialize: function() {
// 初始化加入各種視圖,新建視圖并添加到父視圖指定位置
this.footer = this.$el.find('footer');
this.main = $('#main');
this.todoCollection = new todos;
inputview = new InputView({
collection: this.todoCollection
});
$("#todoapp").prepend(inputview.render().el); //加入輸入框
var toggleAllview = new ToggleAllView({
collection: this.todoCollection
});
this.main.prepend(toggleAllview.render().el); //取得數據后,再初始化
this.allCheckbox = this.$("#toggle-all")[0];
this.listenTo(this.todoCollection, "add", this.addOne);
this.listenTo(this.todoCollection, "reset", this.addAll);
this.listenTo(this.todoCollection, "all", this.render);
// 需要數據的視圖,在獲取數據后定義
this.todoCollection.fetch();
// 狀態視圖
statusview = new StatusView({
collection: this.todoCollection
});
this.footer.append(statusview.render().el); //取得數據后,再初始化
},
render: function() {
// 由于設置了all監聽所有collection的操作,故添加一個項就會被渲染一次,這保證了有改動都會得到渲染到頁面
var done = this.todoCollection.done().length;
var remaining = this.todoCollection.remaining().length;
this.allCheckbox = this.$("#toggle-all")[0];
if (this.todoCollection.length) {
//渲染時執行顯示或隱藏的代碼
this.main.show();
this.footer.show();
this.footer.html();
//如果collection為空的話,則清空footer
} else {
this.main.hide();
this.footer.hide();
}
}, // 實現整體顯示
~~~
**與原子view的區別,在于appview初始化函數除了監聽collection變化外,還初始化各個原子view,并添加到指定界面位置,同時渲染函數根據邏輯需要,渲染整個頁面。**
**以上是對整個todoMVC程序的整體性架構分析,具體交互細節可查看樂帝源代碼。**
- 前言
- 前端編程提高之旅(一)----插件
- 前端編程提高之旅(二)----網站常見特效的jquery實現
- 前端編程提高之旅(三)----瀏覽器兼容之IE6
- 前端編程提高之旅(四)----backbone初體驗
- 前端編程提高之旅(五)----寫給大家看的css書
- 前端編程提高之旅(六)----backbone實現todoMVC
- 前端編程提高之旅(七)----marionette實現todoMVC
- 前端編程提高之旅(八)----D3.js數據可視化data join解析
- 前端編程提高之旅(九)----延遲對象
- 前端編程提高之旅(十)----表單驗證插件與cookie插件
- 前端編程提高之旅(十一)----jquery代碼的組織
- 前端編程提高之旅(十二)----position置入值應用
- 前端編程提高之旅(十三)----jquery選擇器
- 前端編程提高之旅(十四)----jquery DOM操作
- 前端編程提高之旅(十五)----jquery事件
- 前端編程提高之旅(十六)----jquery中的動畫
- 前端編程提高之旅(十七)----jquery中表單、表格和ajax
- 前端編程提高之旅(十八)----移動端web流行交互技術方案研究