1、簡介css
Backbone 是一個 JavaScript MVC 框架,它屬於輕量級框架,且易於學習掌握。
模型、視圖、集合和路由器從不一樣的層面劃分了應用程序,並負責處理幾種特定事件。
處理 Ajax 應用程序或者 SPI 應用程序時,Backbone 多是最好的解決方案。
2、詳細介紹html
Backbone的四大核心組件:git
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