[backbone] Getting Started with Backbone.js

1、簡介css

Backbone 是一個 JavaScript MVC 框架,它屬於輕量級框架,且易於學習掌握。
模型、視圖、集合和路由器從不一樣的層面劃分了應用程序,並負責處理幾種特定事件。
處理 Ajax 應用程序或者 SPI 應用程序時,Backbone 多是最好的解決方案。

 

2、詳細介紹html

Backbone的四大核心組件:git

  • Model
  • Collection
  • View
  • Controller

Modalgithub

Models are the heart of any JavaScript application, containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control.ajax

模型是任何JavaScript應用程序的核心,包含交互式數據以及圍繞它的邏輯的很大一部分:轉換、驗證、計算性能和訪問控制。要建立一個模型,須要擴展 Backbone.Model。數據庫

  例子:瀏覽器

最簡定義:var Game = Backbone.Model.extend({});

拓展:

    var Game = Backbone.Model.extend({
        initialize: function(){
            alert("Oh hey! Backbone!");
        },
          defaults: {
       // default attribute name:
'Default title', releaseDate: 2011, } }); #initialize will be fired when an object is instantiated. #initialize 部分當Game對象實例化的時候將會被觸發 #建立實例化對象
#必須建立一個實例才能在應用程序中使用特定模型
var portal = new Game({ name: "Portal 2", releaseDate: 2011}); #獲取屬性值 var release = portal.get('releaseDate'); #設置屬性值 portal.set({ name: "Portal 2 by Valve"}); #當調用set方法後,僅僅只是改變了內存中的值,若是想要在服務器中持久化值,須要調用save()方法。發送的是POST請求。 portal.save();

 

Collection服務器

Collections in Backbone are essentially just a collection of models. Going with our database analogy from earlier, collections are the results of a query where the results consists of a number of records [models].架構

Backbone中,collection的基本含義就是「許多modal的集合」。若是與咱們早期的數據庫類比,collection就比如是一個查詢的結果集,這個結果集由一系列的記錄[modal]組成。app

  例子:

  

最簡定義:表示這個集合的基本modal類型是Game

var GamesCollection = Backbone.Collection.extend({
  model : Game,
}); 拓展定義:經過新增的方法返回特定的集合數據 add a method that returns only specific games.
var GamesCollection = Backbone.Collection.extend({ model : Game, old : function() { return this.filter(function(game) { return game.get('releaseDate') < 2009; }); } }); 也能夠直接操做一個集合的內容 var games = new GamesCollection(); games.get(0);//或者 games.at(0);
使用 add()/remove() 方法能夠將一個模型添加和移動到集合中。

  App.Collections.Teams = Backbone.Collection.extend({
    model : App.Models.Team
  });

  var teams = new App.Collections.Teams();
  teams.add(team1);
  teams.add(new App.Models.Team({name : "Team B"}));
  teams.add(new App.Models.Team());
  teams.remove(team1);

  console.log(teams.length) // prints 2
  console.log(teams.fetch());//取得集合包含的模型陣列

最後,能夠動態地填充集合
var GamesCollection = Backbone.Collection.extend({
  model : Game,
  url: '/games'
});
 
var games = new GamesCollection();
games.fetch();
這也是經常使用的獲取集合數據的方法

 

View

Backbone 視圖能夠擴展 Backbone.View 函數並顯示模型中存儲的數據。
視圖的主要目的:渲染數據

————————————————————————————————————

(1)定義視圖基準tag

一個視圖提供一個由 el 屬性定義的 HTML 元素。
該屬性能夠是由 tagName、className 和 id 屬性相組合而構成的,或者是經過其自己的 el 值造成的。
若是 el、tagName、className 和 id 屬性爲空,那麼會默認將一個空的 DIV 分配給 el。

例如:

// In the following view, el value is 'UL.team-element'
App.Views.Teams = Backbone.View.extend({
    el : 'UL.team-list'
});

// In the following view, el value is 'div.team-element'
App.Views.Team = Backbone.View.extend({
    className : '.team-element',
    tagName : 'div'
});

// In the following view, el value is 'div'
App.Views.Team = Backbone.View.extend({
});

(2)視圖模型關聯

一個視圖必須與一個模型相關聯。
App.View.Team 視圖被綁定到一個 App.Models.Team 模型實例。

App.Views.Team = Backbone.View.extend({
  el : 'UL.team-list',
  ...
  model : new App.Models.Team
});

 

(3)渲染數據

重寫 render() 方法和邏輯來顯示 DOM 元素(由 el 屬性引用的)中的模型屬性。

#更新用戶界面樣例
App.Views.Team = Backbone.View.extend({
    className : '.team-element',
    tagName : 'div',
    model : new App.Models.Team
    render : function() {
        // Render the 'name' attribute of the model associated
        // inside the DOM element referred by 'el'
        $(this.el).html("<span>" + this.model.get("name") + "</span>");
    }
});

(4)客戶端模板

使用 Backbone 客戶端模板 能夠避免在 JavaScript 中嵌入 HTML 代碼。
使用模板,模板會封裝視圖中常見函數;只指定此函數一次便可。
Backbone 在 underscore.js(一個必須的庫)中提供一個模板引擎。

#使用 underscore.js HTML 模板
<script id="teamTemplate" type="text/template">
    <%= name %>
</script>


#使用 _.template() 函數的視圖
App.Views.Team = Backbone.View.extend({
    className : '.team-element',
    tagName : 'div',
    model : new App.Models.Team
    render : function() {
        // Compile the template
        var compiledTemplate = _.template($('#teamTemplate').html());
        // Model attributes loaded into the template. Template is
        // appended to the DOM element referred by the el attribute
        $(this.el).html(compiledTemplate(this.model.toJSON()));
    }
});

#將 render() 方法綁定到模型變動事件 bind("change",function(){})
#當模型發生更改時,會自動觸發 render() 方法,從而節省數行代碼。
App.Views.Team = Backbone.View.extend({
    model : new App.Models.Team,
    initialize : function() {
        this.model.bind("change", this.render, this);
    } 
})

(5)綜合例子

#定義視圖
var GameView= Backbone.View.extend({
    tagName : "div",
    className: "game",
    render : function() {
        
        //dom way
        //這裏的this.el 至關因而  class = game的那個div節點
        this.el.innerHTML = this.model.get('name');
       
         //jQuery way
        $(this.el).html(this.model.get('name'));
    }
});

#經過dom節點監聽事件
events: {
    'click .name': 'handleClick'
},      
handleClick: function(){
    alert('In the name of science... you monster');
}
    

 

Controller

相似於SpringMVC 中根據不一樣的URI和參數來路由到不一樣的方法進行處理

#基礎定義
var Hashbangs = Backbone.Controller.extend({
  routes: {
    "/":                 "root",
    "/games":        "games",
  },
  root: function() {
    // Prep the home page and render stuff
  },
  games: function() {
    // Re-render views to show a collection of books
  },
});

#或者

var App.Routers.Main = Backbone.Router.extend({

  // Hash maps for routes
  routes : {
    "" : "index",
    "/teams" : "getTeams",
    "/teams/:country" : "getTeamsCountry",
    "/teams/:country/:name : "getTeam"
    "*error" : "fourOfour"
  },

  index: function(){
    // Homepage
  },

  getTeams: function() {
    // List all teams
  },
  getTeamsCountry: function(country) {
    // Get list of teams for specific country
  },
  getTeam: function(country, name) {
    // Get the teams for a specific country and with a specific name
  },
  fourOfour: function(error) {
    // 404 page
  }
});

 
 

http://www.example.com -> 觸發 index()
http://www.example.com/#/teams -> 觸發 getTeams()
http://www.example.com/#/teams/country1 -> 觸發 getTeamsCountry() 傳遞 country1 做爲參數
http://www.example.com/#/teams/country1/team1 -> 觸發 getTeamCountry() 傳遞 country1 和 team1 做爲參數
http://www.example.com/#/something 觸發 fourOfour() -> 以做 * (星號)使用。

注意:

當實例化路由器(控制器)時,會生成 Backbone.history 對象(控制瀏覽器前進或後退的對象);
它將自動引用 Backbone.History 函數。
Backbone.History 負責匹配路由和 router 對象中定義的活動。
start() 方法觸發後,將建立 Backbone.history 的 fragment 屬性。它包含散列片斷的值。該序列在根據狀態次序管理瀏覽器歷史方面十分有用。用戶若是想要返回前一狀態,單擊瀏覽器的返回按鈕。

#所以,爲避免擾亂後退按鈕,請執行以下的代碼:
var ApplicationController = new Controller(); 
Backbone.history.start();

  var router = new App.Routers.Main();
  Backbone.history.start({pushState : true});

 

不得不說的重要屬性和方法

(1)url
定義了使用 Ajax GET 請求從服務器取出 JSON 數據的位置
teams.url = '/getTeams';
teams.fetch(); //Ajax GET Request to '/getTeams'
2)存取 save() / fetch()

Backbone 的一個重要特性是易於經過 Ajax 交互與服務器進行通訊。
在模型上調用一個 save() 方法會經過 REST JSON API 異步將當前狀態保存到服務器。

barca.save();

save()函數將在後臺委託給 Backbone.sync,這是負責發出 RESTful 請求的組件,默認使用 jQuery 函數 $.ajax()。
因爲調用了 REST 風格架構,每一個 Create、Read、Update 或 Delete (CRUD) 活動均會與各類不一樣類型的 HTTP 請求(POST、GET、PUT 和 DELETE)相關聯。
首先保存模型對象,使用一個 POST 請求,建立一個標識符 ID,其後,嘗試發送對象到服務器,使用一個 PUT 請求。

當須要從服務器檢索一個模型時,請求一個 Read 活動並使用一個 Ajax GET 請求。這類請求使用 fetch() 方法。
Fetch() 方法屬於異步調用,所以,在等待服務器響應時,應用程序不會停止。

要肯定導入模型數據或者從中取出模型數據的服務器的位置:

A.若是模型屬於一個 collection,那麼集合對象的 url 屬性將是該位置的基礎,而且該模型 ID(不是 cid)會被附加以構成完整的 URL。

B.若是模型不是在一個集合中,那麼該模型的 urlroot 屬性被用做該位置的基礎


如:
var teamNew = new App.Models.Team({
    urlRoot : '/specialTeams'
});
teamNew.save(); // returns model's ID equal to '222'
teamNew.fetch(); // Ajax request to '/specialTeams/222'
3)parse()
要操做來自服務器的原始數據,可使用集合的 parse() 方法。
App.Collections.Teams = Backbone.Collection.extend({
    model : App.Models.Team,
    parse : function(data) {
        // 'data' contains the raw JSON object
        console.log(data);
    }
});

(4)驗證 validate() 

須要重寫 validate() 方法(在調用 set() 方法時觸發)來包含模型的有效邏輯。
傳遞給該函數的唯一參數是一個 JavaScript 對象,該對象包含了 set()方法更新的屬性,以便驗證那些屬性的條件。
若是從 validate() 方法中沒有返回任何內容,那麼驗證成功。若是返回一個錯誤消息,那麼驗證失敗,將沒法執行 set() 方法。


App.Models.Team = Backbone.Model.extend({
    validate : function(attributes){
        if (!!attributes && attributes.name === "teamX") {
            // Error message returned if the value of the "name" 
            // attribute is equal to "teamX"
            return "Error!";
        }
    }
}


(5)獲取HTML模版代碼

HTML代碼
<script id="teamTemplate" type="text/template">
    <%= name %>
</script>

獲取方法
_.template($('#teamTemplate').html())


(6)綁定模型事件

在 Backbone 0.5.2 以前的版本中,必須使用 underscore.js 中的 _.bindAll() 函數

0.5.2 以前的版本
App.Views.Team = Backbone.View.extend({
    initialize : function() {
        _.bindAll(this, "render");
        //注意這裏的bind只有兩個參數
        this.model.bind("change", this.render);
    } 
})

0.5.2以後的版本
App.Views.Team = Backbone.View.extend({
    model : new App.Models.Team,
    initialize : function() {
        //注意這裏的bind有三個參數
        this.model.bind("change", this.render, this);
    } 
})

 

 

 

 

拓展閱讀:

一、backbone.js手冊

http://documentcloud.github.io/backbone/?cm_mc_uid=04584153933614497181707&cm_mc_sid_50200000=1450061719

http://www.css88.com/doc/backbone/(中文API)

Events
– on
– off
– trigger
– once
– listenTo
– stopListening
– listenToOnce
- Catalog of Built-in Events

Modal
– extend
– constructor / initialize
– get
– set
– escape
– has
– unset
– clear
– id
– idAttribute
– cid
– attributes
– changed
– defaults
– toJSON
– sync
– fetch
– save
– destroy
– Underscore Methods (6)
– validate
– validationError
– isValid
– url
– urlRoot
– parse
– clone
– isNew
– hasChanged
– changedAttributes
– previous
– previousAttributes


Collection
– extend
– model
– constructor / initialize
– models
– toJSON
– sync
– Underscore Methods (28)
– add
– remove
– reset
– set
– get
– at
– push
– pop
– unshift
– shift
– slice
– length
– comparator
– sort
– pluck
– where
– findWhere
– url
– parse
– clone
– fetch
– create


Router
– extend
– routes
– constructor / initialize
– route
– navigate

History
– start

Sync
– Backbone.sync
– Backbone.ajax
– Backbone.emulateHTTP
– Backbone.emulateJSON


View
– extend
– constructor / initialize
– el
– $el
– setElement
– attributes
– $ (jQuery)
– render
– remove
– delegateEvents
– undelegateEvents


Utility
– Backbone.noConflict
– Backbone.$

 

二、underscore.js手冊

http://documentcloud.github.io/underscore/

http://www.css88.com/doc/underscore/(中文API)

針對以下的類型封裝了不少操做的方法
調用方法時,在方法前加上  " _.  "
好比:

Collection中 each 爲 _.each(list, iterator, [context])
_.each([1, 2, 3], alert);
=> alerts each number in turn...
_.each({one : 1, two : 2, three : 3}, alert); => alerts each number value in turn...
map 爲 _.map(list, iterator, [context])
_.map([1, 2, 3], function(num){ return num * 3; });
=> [3, 6, 9]
_.map({one : 1, two : 2, three : 3}, function(num, key){ return num * 3; }); => [3, 6, 9]


find _.find(list, iterator, [context])
var even = _.find([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> 2

filter 爲 _.filter(list, iterator, [context])
var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> [2, 4, 6]

Functions中
bind 爲  _.bind(function, object, [*arguments])
var func = function(greeting){ return greeting + ': ' + this.name };
func = _.bind(func, {name : 'moe'}, 'hi');
func();
=> 'hi: moe'
bindAll 爲  
_.bindAll(object, *methodNames)
var buttonView = {
  label   : 'underscore',
  onClick : function(){ alert('clicked: ' + this.label); },
  onHover : function(){ console.log('hovering: ' + this.label); }
};
_.bindAll(buttonView, 'onClick', 'onHover');
// When the button is clicked, this.label will have the correct value.
jQuery('#underscore_button').bind('click', buttonView.onClick);
delay 
_.delay(function, wait, [*arguments])
var log = _.bind(console.log, console);
_.delay(log, 1000, 'logged later');
=> 'logged later' // Appears after one second.

#如下是比較全面的方法
collections - each
- map
- reduce
- reduceRight
- find
- filter
- where
- findWhere
- reject
- every
- some
- contains
- invoke
- pluck
- max
- min
- sortBy
- groupBy
- countBy
- shuffle
- toArray
- size

arrays - first
- initial
- last
- rest
- compact
- flatten
- without
- union
- intersection
- difference
- uniq
- zip
- unzip
- object
- indexOf
- lastIndexOf
- sortedIndex
- range

functions - bind
- bindAll
- partial
- memoize
- delay
- defer
- throttle
- debounce
- once
- after
- wrap
- compose

objects - keys
- values
- pairs
- invert
- functions
- extend
- pick
- omit
- defaults
- clone
- tap
- has
- isEqual
- isEmpty
- isElement
- isArray
- isObject
- isArguments
- isFunction
- isString
- isNumber
- isFinite
- isBoolean
- isDate
- isRegExp
- isNaN
- isNull
- isUndefined


utility - noConflict
- identity
- times
- random
- mixin
- uniqueId
- escape
- unescape
- result
- template

chaining - chain
- value

 

三、backbone的5個小例子

http://arturadib.com/hello-backbonejs/docs/1.html

相關文章
相關標籤/搜索