backbone.js使用

隨着JavaScript程序變得愈來愈複雜,每每須要一個團隊協做開發,這時代碼的模塊化和組織規範就變得異常重要了。MVC模式就是代碼組織的經典模式。backbone.js就是爲前端開發提供MVC模式滴!css

backebone.js官網介紹

官網左側菜單欄裏面就是backbone.js的所有模塊了html

  • Events 事件:backbone.js是事件驅動的,能夠給對象綁定自定義事件
  • Model 模型:MVC中的M,對數據的操做都在這裏了
  • Collection 集合:是Model的集合
  • Router 路由:爲客戶端路由提供支持,並支持舊瀏覽器
  • History 歷史:處理hashchange或pushState
  • Sync 同步:向服務器進行同步,默認同步方式調用的是jQuery.ajax,能夠重寫Sync修改成其餘同步方式
  • View 視圖:含事件行爲和渲染頁面
  • Utility 工具:爲解決衝突提供工具
  • F.A.O 問答:常見問答
  • Examples 案例:backbone.js有不少案例,直接點擊就能夠查看了

在使用backbone.js的時候,必須引入underscore.js。
此外在官網上面都會給出代碼示例,在代碼的右上角上,有一個運行的按鈕,點擊的運行就能夠看到這段代碼運行的結果啦。前端

MVC

  1. Model
    Model表示數據層,也就是程序須要的數據源,一般使用JSON格式表示。
  2. View
    View表示表現層,也就是用戶界面,對於網頁來講,就是用戶看到的網頁HTML代碼。
  3. Controller
    Controller表示控制層,用來對原始數據(Model)進行加工,傳送到View。

因爲網頁編程不一樣於客戶端編程,在MVC的基礎上,JavaScript社區產生了各類變體框架MVP(Model-View-Presenter)、MVVM(Model-View-ViewModel)等等,有人就把全部這一類框架的各類模式統稱爲MV*。ajax

框架的優勢在於合理組織代碼、便於團隊合做和將來的維護,缺點在於有必定的學習成本,且限制你只能採起它的寫法。數據庫

1.Events

listenTo

$(function(){

    var User = Backbone.Model.extend({
        defaults : {
            name : 'tom'
        }
    });

    var View = Backbone.View.extend({

        initialize : function(){
            console.log("initialize");

            this.listenTo( this.model , 'change' , this.show );     
            // 當與這個view綁定的model數據發生變化的時候,調用show方法

        },
        show : function(model){ // 向頁面中輸出信息
            $('body').append( '<div>'+ this.model.get('name')+ 
            '</br>也能夠經過參數調用</br>' + model.get('name') +'</div>' );
        }

    });


    var tom = new User;
    var view = new View({model:tom});       // 建立view實體
    setTimeout(function(){
        tom.set('name','jack');     // 修改數據
    }, 1000);       // 一秒後修改數據,觸發show


});

listenTo容許一個對象監聽另外一個對象的事件,上面的代碼就是讓view監聽model的change事件,而後調用show()方法編程

2.Model

constructor

var tom = new Backbone.Model({'name':'tom'});  // 建立學生tom
var peter = new Backbone.Model({'name':'peter'}); // 建立學生peter

var students = new Backbone.Collection(); // tom和peter都是學生
students.add( tom );    // 向Collection中添加學生
students.add( peter );

console.log( JSON.stringify(students) ); //[{"name":"tom"},{"name":"peter"}]

用new的方式建立了兩個Model的實例;經過json對象傳參方式給Model的constuctor構造函數傳遞了name屬性。
用new的方式建立了一個Collection實例;調用students的add方法,將tom和peter添加到集合中。
文檔中能夠看出,使用{'name':'tom'}這種方式給Model設置的屬性,實際上會調用model.set()方法。json

extend

var User = Backbone.Model.extend({
sayHello : function(){  //實例方法
        console.log("hello");
    }
},
{
sayWorld : function(){  //靜態方法
        console.log("world");
    }
});

var tom = new User; // 建立一個用戶
tom.sayHello(); // 調用用戶的實例方法
User.sayWorld(); // 直接調用Model的靜態方法

使用extend擴展Backbone.Model,第一個參數是實例對象中的屬性,第二個可選的參數會直接註冊到構造函數成爲靜態方法。這樣即便沒有實例化對象,也能調用Model中定義的方法瀏覽器

var User = Backbone.Model.extend({
    defaults : {        // 默認屬性,可是子類也會繼承
        "name": "tom"
    },
    sayHello : function(){  // 父類的方法
        console.log("hello");
    }
});

var ChildUser = User.extend({   // ChildUser 繼承自User
    sayChild : function(){  // 子類的方法
        console.log("child");
    }
}); 

var child = new ChildUser;  // 建立ChildUser實例
child.sayHello();       // 子類繼承父類sayHello()方法
child.sayChild();       // 子類本身的方法
console.log(child.get("name"));  // 子類繼承父類屬性

extend會正確的設置原型鏈,因此能夠經過extend實現繼承。上面的代碼就是建立父類User,而後子類ChildUser繼承子父類。子類會繼承父類的屬性和方法服務器

initialize

var User = Backbone.Model.extend({
    defaults : {        
        name : 'tom'    // 默認的名字
    },
    initialize : function(){  //當model建立的時候,調用
        console.log("initialize");  

        this.on('change',function(){    // 當數據發生變化的時候觸發
            console.log("此時個人名字是:"+this.get("name"));
        });

    }
});

var tom = new User;
tom.set('name','jack'); // 修改模型的數據,會被change檢測到

若是指定了initialize方法,會在建立實例對象以後調用initialize()
當修改了模型數據(經過set()方法修改數據),會觸發自定義事件。app

var User = Backbone.Model.extend({
    defaults : {        
        name : 'tom',   // 默認的名字
        age : 10
    },
    initialize : function(){  //當model建立的時候,調用
        console.log("initialize");  

        this.on('change:name',function(){   // 只檢測name的變化
            console.log("此時個人名字是:"+this.get("name"));
        });

    }
});

var tom = new User;
tom.set('name','jack'); // 修改模型的數據,會被change檢測到
tom.set('age','20');// 修改年齡不會被change檢測

若是隻想檢測某個屬性的變化,能夠經過添加命名空間的方式區別開事件。經過:的方式給事件添加命名空間。

3.View

extend

var BodyView = Backbone.View.extend({

    el : $('body'), // 若是沒有指定el,el就會是個空div
    events : {
        'click input' : 'sayHello', // 點擊input的時候調用sayHello方法
        'mouseover li' : 'moveLi'// 鼠標懸浮li標籤的時候調用moveLi方法
    },
    sayHello : function(){
        console.log("Hello");
    },
    moveLi : function(){
        console.log("mouseover li");
    }

});

var view = new BodyView;

若是設置了tagName、className、id、attributes屬性(爲視圖設置根元素),那麼view.el就會被建立,若是沒有指定view.el就是個空的div。
Backbone.events能夠寫成對象的形式,給視圖綁定一組自定義事件。

template

var Name = Backbone.Model.extend({
    defaults : {
        name : 'tom'
    }
});

var NameView = Backbone.View.extend({

    initialize : function(){

        this.listenTo( this.model , 'change' , this.showName );

    },
    showName : function(model){
        // $('body').append( "<div>" + model.get("name") + "</div>" );      
        // 不使用template的時候html代碼與js寫在一塊兒
        $('body').append( this.template(this.model.toJSON()) ); 
        // 使用模版以後,html代碼與js代碼相分離
    },
    template: _.template($('#name').html())
    // _.template中傳入須要編譯的模版
    // 返回的結果就是編譯後的html代碼
    // 最後在showName中調用,將編譯後的html顯示到body中
}); 

var name = new Name;
var nameView = new NameView({model:name});
name.set('name','jack');

<script type="text/template" id="name">
    <% for (var i=0;i<5;i++) { %>
        <div><%= name %></div>
    <% } %>
</script>

使用js模版不只能夠將html代碼和js代碼分離,提升可讀性,也能提升開發效率。backbone.js使用的underscore.js中的template

4.Sync

重寫Backbone.sync

Backbone.sync = function(method, model) {
  console.log(method + ": " + JSON.stringify(model));
  model.set('id', 1);   // 模型的特殊屬性
};

var Book = Backbone.Model.extend({
    defaults:{
        title: "The Rough Riders",
        author: "Theodore Roosevelt"
    }
});

var b = new Book;
b.save();       
// create: {"title":"The Rough Riders","author":"Theodore Roosevelt"}
b.save({author: "Teddy"}); 
// update: {"title":"The Rough Riders","author":"Teddy","id":1}

調用模型的save方法,就是委託Backbone.sync對數據進行持久化處理(保存到數據庫),若是驗證成功返回jqXHR,不然返回false。
sync默認狀況下是使用的是jQuery.ajax,能夠經過重寫sync來使用其餘方式進行持久化處理。如WebSockets,XML,或者Local Storage。
上面的代碼就是重寫Backbone.sync的過程。第一次save的時候發送的create請求,第二次save的時候發送的是update請求。
Backbone是如何區分第一次請求仍是第二次請求的呢?
是根據經過model.isNew這個方法進行判斷的。若是模型沒有id屬性,就是表示模型是新模型。能夠經過下面的代碼進行測試

Backbone.sync = function(method, model) {
  console.log(method + ": " + JSON.stringify(model));
  console.log(model.isNew());   // 此時不存在id屬性,因此是true
  model.set('id', 1);   // 模型的特殊屬性
  console.log(model.isNew()); // 此時存在id屬性,因此是false
};

Model.id文檔中指出,若是經過set設置了model的id,就會將這個id拷貝到模型上,做爲model的直接屬性。在下圖中能夠發現經過Model.set('id',1),給attributes中添加了id屬性,也直接給model添加了id屬性。
setId
可是相反的,若是用model.id=1的方式直接給model添加id屬性,是不會拷貝到attributes中的。若是隻是給model直接添加了id,Model.isNew返回的一直都會是true。

Backbone.sync = function(method, model) {
  console.log(method + ": " + JSON.stringify(model));
  console.log(model.isNew());   // 返回true
  model.id=1;   // 給model直接添加id屬性
  console.log(model.isNew()); // 返回true
};

attributeId

友情連接

相關文章
相關標籤/搜索