Backbone中文學習文檔:http://www.css88.com/doc/backbone/javascript
來到公司已經有一段時間了,到如今深深的感受到本身的能力弱的像只周黑鴨,又幹澀又黝黑,充滿了麻(手麻腦殼也麻)和辣(欲哭無淚),作全棧先後端都得好好學,這不,一個開源項目中出現Backbone,??!??...這是哪一個朝代的語言?左打聽右詢問,才知道是一個上古框架,雖然古老可是很實用也必需要用到(我估計確定有先東西替代它了,應該會更好用更人性化),懂前端人天然明白。因此各類掰翻找查,在一個作前端姑娘的博客裏發現這篇讓我看起來很舒服的Backbone,博客我先摘過來,放本身家裏習慣點,我在裏面也適當加一些本身理解的小東西,算是向這美女姑娘致敬,謝謝,下面會標明出處(不要追究個人法律責任,我不懂法,可是守法),不會白拿的,伸手黨確實可惡!css
so,什麼way,開始學吧。。。 。。。html
什麼是BACKBONE?前端
即一個實現了WEB前端的MVC模式的JS庫,像JQUERY,angularjs等。java
什麼是MVC模式?jquery
模式:一種解決問題的通用方法git
--設計模式:工廠模式,適配器模式,觀察者模式等angularjs
--框架模式:MVC ,MVP,MVVM等github
思想:模型和試圖分離,經過控制器來鏈接他們。關於WEB前端MVC模式。web頁面自己就是一個大的VIEW,不容易作到分離操做。其次BACKBONE適合複雜的大型開發。web
圖片解析MVC、MVP、MVVM:
events : 事件驅動方法
model :數據模型
collection: 模型集合器
router :路由器(hash)
history:開啓歷史管理
SYNC : 同步服務器方式
view : 視圖(含事件行爲和渲染頁面)下面,咱們經過一張圖,瞭解一下他們之間的關係。
collection是model數據的集合。指對多條數據的操做,view是渲染頁面的展現。router經過hash指,將對應的數據呈如今不一樣的view中,固然router必須指定歷史管理,歷史管理主要是檢測hash的變化。模型數據的修改經過ajax的方式,傳輸到服務器中,進行同步服務器sync。
1:基於jquery(針對試圖的實現具體的效果,操做dom),服務器環境,面向對象
2:基於underscore.js庫--做用是:提供了80多種方法,包括數組,對象,事件中的方法,有利於對backbone中的數據模型和集合的操做。
下面來看一個單個模型實際列子,可自行貼代碼測試:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="utf-8"> 5 <title>測試backbone</title> 6 <!-- 按照前後順序,不然會報錯 --> 7 <script src = "jquery-3.1.0.min.js"></script> 8 <script src = "underscore-min.js"></script> 9 <script src = "backbone-min.js"></script> 10 <script type="text/javascript"> 11 var model = new Backbone.Model(); //建立一個backbone的模型實列 12 model.set('name' , 'jt'); 13 console.log( model . get('name')); //使用set和get方法來獲取屬性值 14 </script> 15 </head> 16 <body> 17 </body> 18 </html>
控制檯打印出來的爲:
下面看下將多個模型數據鏈接起來的列子,這裏再也不整個貼代碼,看js便可:
1 var model_1 = new Backbone.Model({'name':'jt'}); //直接賦值進行數據初始化 2 var model_2 = new Backbone.Model({'name':'lkm'}); 3 4 //建立一個數據模型集合 5 var models = new Backbone.Collection(); 6 //經過add方法將單個模型添加到模型集合中 7 models.add(model_1); 8 models.add(model_2); 9 console.log(JSON.stringify(models));//JSON解析,將數據集合打印出來
控制檯打印出來的效果爲:
其實至關於類裏面的繼承,子類可使用其繼承的方法和屬性,在BACKBONE裏面,新建立的實列可使用其模型的方法。看下實列代碼:
1 //模型的構造函數的擴展,至關於繼承,則聲稱的實列可使用其父類的方法 2 var M = Backbone.Model.extend({ 3 //第一個參數寫實列方法,第二個參數寫靜態方法 4 aaa : function(){ //實列方法 5 console.log('jt'); 6 } 7 },{ 8 bbb : function(){ //靜態方法 9 console.log('lkm'); 10 } 11 }); 12 var model = new M; 13 model.aaa(); //實列方法,直接使用實列來進行調用 14 M.bbb(); //靜態方法是掛載在構造函數下面的,因此須要使用構造函數來直接調用
控制檯打印結果以下:
再來看下屬性的列子,可自行貼代碼進行測試:
1 var M = Backbone.Model.extend({ 2 defaults: { 3 name : 'jt' 4 } 5 }); 6 var model = new M; 7 console.log(model.get('name'));
這裏defaults至關因而默認的數據值,當進行建立實列時,進行GET方法調用時,直接使用的是默認的數據值。
關於在BACKBONE中對象如何實現繼承,咱們直接看下代碼:
1 var M = Backbone.Model.extend({ 2 aaa: function(){ 3 console.log('婷風'); 4 } 5 }); 6 var childM = M.extend(); //繼承父類的模型 7 var model = new childM; //聲稱一個實列的對象 8 model.aaa();
控制檯打印結果爲:
BACKBONE有不少事件,好比on事件,這裏了舉個栗子。具體的可看官網給的列子。
object.on(event, callback, [context])
在 object 上綁定一個callback回調函數。 只要event觸發,該回調函數就會調用。
1 var M = Backbone.Model.extend({ 2 defaults : { 3 name : '婷風' 4 }, 5 initialize : function(){ 6 this.on('change',function(){ 7 console.log(123); 8 }); 9 } 10 }); 11 12 var model = new M; 13 model.set('name' , 'lkm');
這裏給初始的default改變了其name屬性,因此會觸發change事件,從而發生相對應的行爲。
打印結果以下:
上面那個是無論什麼屬性發生改變都會觸發該事件,下面來看下特定的事件觸發。
1 var M = Backbone.Model.extend({ 2 defaults : { 3 name : '婷風' 4 }, 5 initialize : function(){ 6 this.on('change : name',function(){ //這裏指定了只當name屬性發生改變時纔會觸發該事件 7 console.log(123); 8 }); 9 } 10 }); 11 var model = new M; 12 model.set('name' , 'lkm');
下面來看下回調函數裏面帶參數的,看下代碼
1 var M = Backbone.Model.extend({ 2 defaults : { 3 name : '婷風' 4 }, 5 initialize : function(){ 6 this.on('change : name',function(model){ 7 console.log(model); 8 }); 9 } 10 }); 11 var model = new M; 12 model.set('name' , 'lkm');
咱們看下打印臺打印出來的東西:
打印出來的都是model裏面的一些屬性。可自行貼碼測試。
固然,確定是MODEL和view想結合,舉個列子看看。
1 $(function(){ 2 var M = Backbone.Model.extend({ 3 defaults : { 4 name : '婷風' 5 } 6 }) ; 7 //建立一個試圖,listenTo比on多一個參數,改寫了this指向 8 var V = Backbone.View.extend({ 9 initialize : function (){ 10 this.listenTo(this.model , ' change' , this.show); //操做的元素 |數據發生改變的時候,發生show事件 11 }, 12 show : function (model){ 13 $('body').append('<div>' + model.get('name') + '</div>'); 14 } 15 }); 16 var m = new M; 17 var v = new V({model:m}); 18 m.set('name' , 'jt' ); 19 });
打印出來的結果以下:該DIV渲染到body中
Backbone.sync 是 Backbone 每次向服務器讀取或保存模型時都要調用執行的函數。 默認狀況下,它使用 jQuery.ajax 方法發送 RESTful json 請求,而且返回一個 jqxhr。 若是想採用不一樣的持久化方案,好比 WebSockets, XML, 或 Local Storage,咱們能夠重載該函數。
Backbone.sync 的語法爲 sync(method, model, [options])。
默認 sync 映射 REST 風格的 CRUD 相似下面這樣:
來看下列子:
1 Backbone.sync = function(method , model){ //AJAX請求 2 cnsole.log(method + ":" + JSON.stringify(method)); 3 } 4 5 var M = Backbone.Model.extend({ 6 defaults : { 7 name : '婷風' 8 }, 9 url : '/user' //後臺的地址 10 }) ; 11 var m = new M; 12 m.save(); //將數據保存到服務器上 13 m.save({name : 'jt'});//更新操做
咱們看下控制檯效果:
再來看下如何更新數據庫裏面的數據:
1 Backbone.sync = function(method , model){ //AJAX請求 2 console.log(method + ":" + JSON.stringify(method)); 3 } 4 var C = Backbone.Collection.extend({ //集合綁定事件 5 initialize : function(){ 6 this.on('reset', function(){ //當服務器數據獲取成功,調用該事件 7 console.log('jt'); 8 }) 9 }, 10 url : '/users' 11 }); 12 var models = new C; 13 models.fetch();//從服務器上進行數據的更新
看下控制檯打印效果:
其實原理和咱們日常請求數據的增刪改查是同樣的,後端給API,前端根據字段發送AJAX請求,獲取數據等。
經過 Backbone.Router.extend 來建立路由模型,連接到不一樣的指定的動做和事件.當應用已經所有連接到路由時,需利用Backbone.history.start() 或者Backbone.history.start({pushState: true}) 來確保驅動初始化 URL 的路由。
咱們來具體的看個列子:
1 //路由與歷史管理 2 var Workplace = Backbone.Router.extend({ 3 routes: { 4 "help" : "help" , //對應的調用方法 #help 5 "search/:query" : "search" , #search/help 6 "search/:query/p:page" : "search" #search/query/p3 7 } , 8 9 help : function(){ 10 console.log('111'); 11 //alert('111'); 12 }, 13 14 search : function(query , page){ 15 console.log('222'); 16 //alert('333'); 17 } 18 }); 19 var w = new Workplace ; 20 Backbone.history.start(); //保證路由在瀏覽器中有歷史管理
開始建立一個自定義的路由類。當匹配了 URL 片斷便執行定義的動做,並能夠經過routes 定義路由動做鍵值對。 注意:要避免在路由定義時使用前導斜槓!!!!!
什麼叫事件委託呢?即事件代理,利用冒泡原理,將某一元素的事件,委託給其它元素處理的事件。
好處:提升性能 | 新添加的元素,依然保留了該事件。
1 //事件委託 2 $(function(){ 3 var V = Backbone.View.extend({ 4 el : $('body'), //el當前的委託人。用BODY做爲委託人 5 events : { //事件 6 'click input' : 'aaa' , 7 'mouseover li ' : 'bbb' 8 }, 9 aaa : function(){ 10 console.log('aa'); 11 }, 12 bbb : function(){ 13 console.log('bb') 14 } 15 }); 16 17 var view = new V; 18 });
看下html相對應的代碼:
1 <input type="button" value="name"> 2 <ul> 3 <li>11111111</li> 4 <li>22222222</li> 5 <li>33333333</li> 6 <li>44444444</li> 7 </ul>
當點擊Input時候,發生click事件,觸發aaa,當鼠標移入li上時,觸發bbb。
好處:更好的實現mvc機制,讓js的操做與試圖進行分離。一般是template:_.template($('#template').html())這種寫法。
1 //前端模板 :更好的讓js的操做與視圖進行分離 2 $(function(){ 3 var M = Backbone.Model.extend({ 4 defaults : { 5 name : '婷風' 6 } 7 }) ; 8 //建立一個試圖,listenTo比on多一個參數,改寫了this指向 9 var V = Backbone.View.extend({ 10 initialize : function (){ 11 this.listenTo(this.model , ' change' , this.show); //操做的元素 | 數據發生改變的時候,發生show事件 12 }, 13 show : function (model){ 14 $('body').append(this.template(this.model.toJSON() )); //調用模板的方法 15 }, 16 template : _.template($(' #template').html()) 17 }); 18 var m = new M; 19 var v = new V({model:m}); 20 m.set('name' , 'jt' ); 21 });
html代碼以下:
<div id="template"></div>
效果地址:http://www.css88.com/doc/backbone/examples/todos/index.html
下載地址:https://github.com/foreverjiangting/backbone/tree/master/examples/todos
主頁html代碼以下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="utf-8"> 5 <title>Backbone.js Todos</title> 6 <link rel="stylesheet" href="todos.css"/> 7 <script type="text/javascript" src="jquery.js"></script> 8 <script type="text/javascript" src="underscore-min.js"></script> 9 <script type="text/javascript" src="backbone.js"></script> 10 <script src="backbone.localStorage.js"></script> 11 <script src="todos.js"></script> 12 13 </head> 14 <body> 15 <div id="todoapp"> 16 <header> 17 <h1>Todos</h1> 18 <input id="new-todo" type="text" placeholder="What needs to be done?"> 19 </header> 20 21 <section id="main"> 22 <input id="toggle-all" type="checkbox"> 23 <label for="toggle-all">Mark all as complete</label> 24 <ul id="todo-list"></ul> //包含每一個li元素 25 </section> 26 27 <footer> 28 <a id="clear-completed">Clear completed</a> 29 <div id="todo-count"></div> 30 </footer> 31 32 </div> 33 34 <div id="instructions"> 35 Double-click to edit a todo. 36 </div> 37 38 <!-- 單個li的Templates --> 39 40 <script type="text/template" id="item-template"> 41 <div class="view"> 42 <input class="toggle" type="checkbox" <%= done ? 'checked="checked"' : '' %> /> 43 <label><%- title %></label> 44 <a class="destroy"></a> 45 </div> 46 <input class="edit" type="text" value="<%- title %>" /> //雙擊li中的輸入框進行編輯 47 </script> 48 49 50 <!-- 底部的Templates --> 51 <script type="text/template" id="stats-template"> 52 <% if (done) { %> 53 <a id="clear-completed">Clear <%= done %> completed <%= done == 1 ? 'item' : 'items' %></a> 54 <% } %> 55 <div class="todo-count"><b><%= remaining %></b> <%= remaining == 1 ? 'item' : 'items' %> left</div> 56 </script> 57 58 </body> 59 </html>
-----------------------------------------------------------------------------------------------------------------
so,any什麼。。。 。。。
做者:婷風