一種解決問題的通用方法,咱們叫作模式。前端
設計模式:工廠模式,適配器模式,觀察者模式等,推薦js設計模式這本書。設計模式是一種思想。web
框架模式:MVC,MVP,MVVM等。框架模式是開發項目的一種方案。ajax
MVC指的是什麼?M:model(模型),V:view(視圖),C:controller(控制器)設計模式
MVC模式的思想,把模型和視圖分離,經過控制器來鏈接它們。服務器
Events模塊是事件模塊,其餘模塊都繼承了Events模塊,所以都有事件模塊的功能。mvc
Model就是模型,Collection是集合,它能夠添加多個模型,叫作模型的集合。Model通常對應一條數據,而Collection通常對應多條數據。app
View就是視圖,可是這裏的視圖跟傳統的不同,View不只包括視圖顯示還包括事件監聽(這裏能夠稱做controller),好比說:視圖上會綁定事件回調函數。框架
model能夠直接跟view關聯操做,model傳數據給view,view就顯示這個數據。一個model最好對應一個view。Collection也能夠直接跟view關聯操做。函數
Router就是路由的意思。若是咱們的項目是在一個頁面上進行開發的,而不是經過跳轉頁面。這時,就不會出現歷史管理,那若是要在一個頁面上進行開發時,出現歷史管理,那麼就必須用hash值或者HTML5的history API。
Router的做用就是在一個頁面上進行數據的對應。好比:數據從model傳給Router,而後Router經過Hash值取到對應的數據,最後,Router把對應的數據生成到view中,達到一一對應的效果。Router操做hash值,必須經過history來管理。history的設計是這樣的:若是支持HTML5,就使用history API,或者監聽onhashchange事件。不支持的話,就使用一個定時器來輪詢hash值的變化。
對model進行操做時,須要跟服務器進行交互,那麼model與服務器進行交互的方法就是Sync,Sync使用的是ajax方法跟服務器進行交互。若是你的模型跟服務器交互使用的是ajax的話,那麼就直接使用Sync方法就好了,若是不是,那麼就須要重寫Sync方法。
這裏面全部的模塊都有Controller的影子,可是Router模塊是最明顯的,所以有時,咱們叫Router爲Controller。
Backbone的使用須要依賴於其餘的庫:
underscore.js,此庫裏面有不少基本方法,能夠幫Backbone的mode模塊處理數據和集合,這樣Backbone就不用寫這些方法了。
jQuery或zepto,此庫能夠幫助view模塊實現不少頁面效果,同時它裏面有不少DOM操做的方法,以及Ajax方法。
Backbone的基本使用:
直接建立對象
第一個例子
var model = new Backbone.Model(); model.set("name","hello"); model.get("name"); //hello
第二個例子
var model2 = new Backbone.Model({"name":"hello"}); var model3 = new Backbone.Model({"name":"hi"}); var models = new Backbone.Collection(); models.add(model2 ); models.add(model3 ); JSON.stringify(models); //[{"name":"hello"},{"name":"hi"}]
給構造函數添加實例方法和靜態方法
第一個例子
var M = Backbone.Model.extend({ aaa:function(){} },{ bbb:function(){} }); //這裏的aaa就是實例方法,bbb方法就是靜態方法。 var model = new M(); model.aaa(); M.bbb(); 第二個例子 var M = Backbone.Model.extend({ defaults:{name:"hello"} }) var model = new M(); model.get("name"); //"hello"
繼承操做
var M = Backbone.Model.extend({ aaa:function(){alert(3)} }); var childM = M.extend(); //繼承,M是父類,有aaa實例方法,childM是子類,繼承M,因此也有了父類M的aaa方法 var model = new childM(); model.aaa(); //打印出3
自定義事件
第一個例子
var M = Backbone.Model.extend({ defaults:{name:"hello"} , initialize : function(){ //new M時,會執行這個初始化函數。 this.on("change",function(){ //監聽change事件 alert(1); }) } }) var model = new M(); model.set("name","hi"); //改變模型的name值時,就會觸發change事件,彈出1.其實這裏只要改變模型,就會觸發。
第二個例子
var M = Backbone.Model.extend({ defaults:{name:"hello"} , initialize : function(){ //new M時,會執行這個初始化函數。 this.on("change:name",function(model){ //監聽change事件 //回調方法中的參數就是model對象。 }) } }) var model = new M(); model.set("name","hi"); //改變模型的name值時,就會觸發change事件,彈出1.改變模型的其餘數據,這裏就不會觸發。
第三個例子
var M = Backbone.Model.extend({ defaults:{name:"hello"} }); var V = Backbone.View.extend({ initialize:function(){ //new V時,會跟這個視圖的model綁定change事件,回調方法是視圖的show方法 this.listenTo(this.model, "change", this.show); //listenTo方法跟on同樣是綁定事件的,可是listenTo能夠設置this的指向,它多一個參數。它的意思就是:給this.model綁定change事件。 }, show:funtion(model){ alert(model.get("name")); } }); var m= new M(); var v = new V({model:m}); m.set("name","hi"); //改變模型的name值時,就會觸發change事件,在視圖中彈出模型設置的name值。
數據與服務器的操做
第一個例子
Backbone.sync = function(method , model){ alert(method); model.id = 1; //服務器經過model的id屬性來識別模型的惟一性 //method的值有五種:1. create(post請求)。2.update(put請求)。3.delete(delete請求)。4.read(get請求)5.patch(patch請求)。在這個例子中,當第一次調用sava方法時,是post請求,在服務器上建立name:"hello"。當第二次調用sava({name:"hi"})方法時,是put請求,由於服務器上這時已經有name值了,如今是更新服務器上的name值爲"hi"。 } var M = Backbone.Model.extend({ defaults:{name:"hello"}, url : "/user" }); var m = new M(); m.save(); //保存model的數據,把數據同步到服務器上,調用的是Backbone.sync方法(默認使用ajax請求,若是引入了jQuery,就會使用jQuery的ajax)。咱們只要在model中設置url屬性就好了,這樣程序才知道把數據同步到哪一個服務器上,其實就是同步到這個url上。固然你能夠重寫Backbone.sync方法,來改變使用ajax方式同步服務器的操做。 m.save({name:"hi"});
第二個例子
Backbone.sync = function(method , model){ alert(method); //當調用fetch方法時,也會執行sync方法,這時的method就是read(get請求),從服務器獲取數據。 } var C = Backbone.Collection.extend({ initialize:function(){ this.on("reset",function(){ //數據獲取成功後,就會觸發這個reset事件 alert(1); }) }, url : "/users" }); var models = new C(); models.fetch(); //從服務器/users路徑獲取數據
路由與歷史管理
var route = Backbone.Router.extend({ routes:{ "help":"help", "search/:query":"search", //:表明這個字符是變量,意思就是query是一個變量,假設query=chaojidan,那麼這裏的"search/chaojidan"對應search函數。 "search/:query/p:page": "search" }, help:function(){ alert(1); }, search:function(query,page){ alert(2); } }); var w = new route(); Backbone.history.start(); //必須執行這個代碼,路由才能正常使用。這時,歷史管理也實現了。移動端開發很適合這種單頁操做,不用頁面的跳轉,只要改變hash值就能進行功能的實現。
事件委託
var V = Backbone.View.extend({ el:$("body"), events :{ "click input": "aaa", "mouseover li" : "bbb" }, aaa:function(){ alert(1); }, bbb:function(){ alert(2); } }); var view = new V; //當new這個視圖後,頁面上的input就會綁定click事件,只要點擊input,就會執行aaa方法。同時,頁面上的li元素也會綁定mouseover事件。視圖的el指向的是頁面的body元素,是el指向的元素就是此視圖的根元素,事件的綁定會從這個根元素上開始查找元素。
前端模板
<script type="text/template" id="template"> <div><%= name %></div> </script> var M = Backbone.Model.extend({ defaults:{name:"hello"} }); var V = Backbone.View.extend({ initialize:function(){ this.listenTo(this.model, "change", this.show); //給this.model綁定change事件,事件響應函數是this.show,this.show方法中的this指向是this(view),而不是this.model(model),這就是listerTo方法跟on的不一樣。 }, show:funtion(model){ $("body").append( this.template( this.model.toJSON() ) ); //this.model.toJSON() = {name:hi},套入模板後變成<div>hi</div>,最後添加到頁面上。這裏作到了html和js的分離。html用模板來實現。 }, template:_.template($("#template").html()); }); var m= new M(); var v = new V({model:m}); m.set("name","hi");