backbone詳細解析

Backbone  簡介

中文APIhttp://www.csser.com/tools/backbone/backbone.js.html javascript

英文APIhttp://backbonejs.org/ css

Backbone是構建javascript應用程序的一個優秀的類庫。他簡潔、輕量級、功能實在。 html

backbone採用MVC模式,自己提供了模型、控制器和視圖從而咱們應用程序的骨架便造成。 java

backbone依賴於underscore,他是一個類庫,提供了60多個函數處理數組操做、函數綁定,以及javascript模板機制。 node

模型 數組

模型是保存應用程序數據的地方。咱們能夠把模型看作對應用程序原始數據的精心抽象,而且添加了一些工具函數和事件。 函數

咱們可使用Backbone.Modelextend方法來建立Backbone模型: 工具


var Note = Backbone.Model.extend({

     defaults:{
         title:’’//用於定義屬性的
       created_at:new Date(); //定義一個時間的對象
     },

    initialize: function () { }, //當即執行函數一直處於監聽的狀態

     validate: functin () { }, //驗證

});



  extend 的第一個參數是一個對象,他成爲了模型實例的屬性;

第二個參數是可選的類屬性的哈希,經過屢次調用extend能夠生成模型的子類,他們將繼承父親全部類和實例屬性: this

var Note = Backbone.Model.extend({    //實例屬性
    instanceProperty: 'foo'}, {    //類屬性
    classProperty: 'bar'});
   assertEqual(User.instanceProperty, 'foo');
   assertEqual(User.classProperty, 'bar');



 

當模型實例化時,他的initialize方法能夠接受任意實例參數,其工做原理是backbone模型自己就是構造函數,因此可使用new生成實例: spa

var Note = Backbone.Model.extend({
    initialize: function (name) { //模型實例化時會馬上執行       
     this.set({name: name});
    }
    });

    var note = new Note('Mickey');
    assertEqual(note.get('name'), 'Mickey');



 

Ps assertEqual用於判斷相等

 

模型和屬性

使用setget方法設置獲取實例的屬性:

var note = new Note();
note.set({ name: 'Mickey' });
note.get('name'); //Mickey user.attributes;//{name: 'Mickey'}
 
 

咱們看到其實user.arributes是一個對象字面量,咱們不會直接操做他,由於咱們使用get/set方法能夠進行咱們的驗證流程。

使用clear方法清除實例的屬性

var note = new Note();
note.set({ name: 'Mickey' });
note.clear(); //清除note的所有屬性



 

判斷實例是否有某個屬性或者返回某個屬性

var note = new Note();
note.set({ name: 'Mickey' });
note.has(‘name’)  //判斷實例是否有name的屬性
note.get(‘name’) //返回note實例的title屬性值



 

咱們使用validate方法來校驗一個實例屬性,默認狀況沒有任何驗證,如果咱們須要驗證的話:

var Note = Backbone.Model.extend({
validate: function (attr,options) {        
if (!attr.name || attr.name.length < 3) {           
 return '名稱不能爲空或者小於3';
        }
    }
});



 

若是屬性合法,validate不會理睬之,不合法能夠返回錯誤字符串或者Error對象,校驗失敗get/set方法就會觸發error事件:

var note = new Note();
note.bind('error', function (model, error) {    //錯誤處理函數});
note.set({ name: 'm' });//給特定集合添加一個錯誤處理程序note.set({ name: 'm' }, { error: function (model, error) { } });



 

固然咱們也能夠在initializa裏面添加對錯誤事件的處理


initialize: function () {  
//當驗證失敗的時候當即執行該函數
this.on (‘invalid’,function ( model, error ) { 
    console.log ( error )
}
    
//其餘事件實例
this.on(‘change’,function (model,options) { //當屬性發生變化的時候觸發該函數
     console.log ( ‘實例屬性發生了變化’ )
}
//當 ‘change’ 改成 ‘change:name’時 則僅當name屬性發生變化時觸發
    
}



使用hash名爲default的對象來指定默認屬性,在建立一個實例模型時,任何沒有指定值的屬性都會被設置爲默認值:
var NoteModel = Backbone.Model.extend({
    defaults: { name: 'Mickey'}
});
assertEqual((new Chat).get('name'), 'Mickey');




 

集合

backbone中,模型實例的數據存放在多個集合中,爲何模型之間要使用獨立的集合,其緣由有點複雜,但在實際中咱們常常這麼作(雖然我還沒作過)。

針對模型,能夠經過擴展backbone.collection來建立一個集合:
var Collection = Backbone.Collection.extend({
model: Node //用於規定node的類型
initialize: function (){} //實例化集合時當即執行的函數
});


 

在上面的例子中,咱們覆蓋了model屬性來指定與集合相關聯的模型(這裏是Node模型),雖然這個步驟不是必須的,可是爲該集合設置一個默認的模型指向每每能派上大用場。

一般集合會包含單個模型的一個實例,而不是不一樣模型的多個實例。

在建立一個集合時,能夠傳遞一個模型數組,好比backbone模型,若是定義了一個初始化實例函數,在初始化時就會調用之:


var collections = new Collection([{ name: 'Mickey' }, { name: 'Miki'}]);


另外一種方法是使用add方法爲集合添加模型:

collections.add({ name: 'Mickey' });
collections.add([{ name: 'Mickey' }, { name: 'Mcikey' }]);
 

還有一種方法就是先實例化模型再加入


var note1 = new Note ({name:’mickey’});
var note2 = new Note ({name:’Miki’});
var collections = new Collection ([note1,note2]);

 

傳遞一個對象時,若是該對象已經存在,則默認不會覆蓋,除非設置merge


//此處假設Note模型中有id屬性
var collections = new Collection;
collections.add ({id:1, name:’mickey’})
collections.add ({id:1, name:’miki’}) //此時collections中並不存在miki
collections.add ({id:1, name:’miki’}, {merge:true}) //此時id爲1的模型的name爲//miki

 

一些模型的基本操做


var note1 = new Node({name:’mickey’})
var note2 = new Node({name:’miki’})
var note3 = new Node({name:’js’})
var collections = new Collection ([note1,note2])//新建一個集合
collections.remove(note1) //移除note1 實例 collections剩下note2
collections.reset([note1,note2])//覆蓋全部模型 collections此時爲note1,note2
collections.pop()
//刪除最後一個模型 並返回該模型 此時collections爲note1 push()則相反
collections.shift()
//刪除第一個模型 並返回該模型 此時collections刪除note1 unshift()則相反
collections.add(note3,{at:1})//將note3插入到索引號爲1的位置上,也就是第二個元素
collections.set([note1,note2])
//插入覆蓋模型,若是元素已經在,若是不一樣則合併,不然不操做。若是集合中沒有該模型,則插入,若是集合中有該模型,參數中沒有,則刪除模型
collections.get(3) //獲得id號爲3的模型
collections.at(1)  //獲得索引號爲1的模型

在爲集合添加模型時會觸發add事件:


collections.bind('add', function (user) {    //...});//移除一個模型collections.bind('remove', function (user) {    //...});//根據模型id獲取模型var note = users.get('moduleId');//集合中模型被修改後出發change事件var note = new User({ name: 'Mickey' });
var collections = new Backbone.Collection();
collections.bind('change', function (rec) {//改變一個記錄});
collections.add(user);
note.set({ name; 'Miki'});

 控制集合內部順序

一個集合內部元素順序能夠經過comparator方法控制,該方法的返回值即是你但願集合內部排序的規則:


var Collection = Backbone.Collection.extend({
comparator: function (user) {        
return user.get('name');
    }
});
 

  返回值能夠是值或者數字,具體例子咱們下次有機會來試試看。

 

 視圖

 

  backbone的視圖並非模板,而是一些控制類,他們處理模型的表現。

 

  在不少MVC中視圖通常指html或者模板,他們在控制器中處理事件和渲染,但backbone中視圖:




視圖表明一個UI邏輯塊,負責一個簡單的DOM內容
var NoteView = Backbone.View.extend({
    initialize: function () { }, //初始化當即執行的函數
    render: function () { }  //渲染函數
});

 

 

無論視圖有沒有被插入頁面,每一個視圖都知道當前的Dom元素,即this.elel是從視圖的tagNameclassName或者id等屬性中建立的元素,沒有這些值el就是空div


var NoteView = Backbone.View.extend({
    tagName: 'li',
className: 'view'});
var userView = new UserView();//結果<li class="users"></li>



 

 

如果但願視圖綁定到頁面上已存在的元素上,直接指定el就好(必須在頁面加載後才能指定哦,否則找不到):







 



var NoteView = Backbone.View.extend({
    el: $('.view')
});//也能夠實例化一個視圖時傳遞el(tagName、className\id)new UserView({ id: 'id' });


 

  

渲染視圖

每一個視圖都有一個render方法,默認狀況下沒有任何操做,一旦視圖須要重繪便會調render方法,不一樣的視圖用不一樣功能的函數來覆蓋函數,以處理模板渲染,並使用新的html來更新el

var NoteView = Backbone.View.extend({
    template: _.template($('#tmpt').html()), //使用的模板
    render: function () {   //渲染操做
        $(this.el).html(this.template(this.model.toJSON()));       
 return this;
    }
});






 

backbone自己並不知道咱們是怎麼渲染視圖的,咱們能夠本身生產元素也可使用模板類庫(通常用這個)。

在前面的代碼中,咱們使用了this.model的本地屬性,他指向一個模型實例,在實例化時傳遞到視圖中,模型的toJSON方法實際上返回模型未加工時的原始屬性,能夠在模板中使用:

new NoteView({ model: new Note });
相關文章
相關標籤/搜索