Backbone.js 是一個 Javascript Framework,它提供了簡單的view和model的使用,讓程式碼看起來比較不會髒亂,開發者也比較好維護。另外Backbone.js不是MVC的Framework,因為並沒有controller。

Backbone.js跟jQuery搭配操作DOM Tree,在使用上也還算方便

Backbone.js主要有以下四種類別:

  • Model
  • View
  • Router
  • Collection

使用Backbone.js

<!-- 使用Backbone.js必須也加入它所依賴的函式庫Underscore.js -->
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.3/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.9/backbone-min.js"></script>

Model:存放資料的類別,同時也可以綁定一些資料異動時的事件
基本Model操作:

//建立Model Person
var Person = Backbone.Model.extend({
	//initialize 為Model的Constructor
	initialize: function() {
		console.log('Build');
	},
	//預設值
	defaults : {
		'name':'John',
		'age':'13'
	}
});

//建立Model
var man = new Person({'name':'Johnson','age':'25'});

//設定參數
man.set('name','Tom');
//取得參數
console.log(man.get('name'));

//將Model轉成JSON
console.log( man.toJSON() );

Model event控制

var Person = Backbone.Model.extend({
	//initialize 為Model的Constructor
	initialize: function() {
		console.log('Build');
		//監聽事件,當name被修改時觸發(change:name之間不可有空白)
		this.on('change:name',function(){
			alert('name already change');
		});
	},
	defaults : {
		'name':'Johnson',
		'age':'25'
	}
});

View:用來代表HTML中所指定的區塊,並針對初始化其事件做設定
View的操作
HTML:

<div id="doc">
	<button class="action">Button</button>
	<ul>
		<li class="test"><a href=""></a></li>
	</ul>
</div>

View(將上段HTML建成View)

//建立View
var theView = Backbone.View.extend({
	//View的root element
	el : $('#doc'),
	//Constructor
	initialize: function() {
		alert("View is Build");
		//直接呼叫open function
		this.open();
	},
	//事件(對應到render function)
	events: {
		'click .action' : 'open',
	},
	//render function
	open: function(e){
		//取出匯入Model的值
		alert( this.model.get('name')  );
		//this.$el 代表 view指定的el元素(jQuery Object)
		alert( this.$el.attr('id') );
		//$(e.target) 代表 觸發click event的 .action 元素(jQuery Object)
		alert( $(e.target).html() );
	},
});

Model

//建立Model(這裡沒有使用Model.extend繼承Model,而是直接手動建立一個新Model物件)
var myModel = new Backbone.Model({
	'name':'Johnson',
	'age':'30'
});

產生View Object並傳入Model

var view = new theView({ 'model': myModel });

View 載入 template
HTML

<div id="doc">
	<script type="text/template" id="search_template">
		<label>Search</label>
		<input type="text" id="search_input" />
		<input type="button" id="search_button" value="Search" />
	</script>
</div>

View

var SearchView = Backbone.View.extend({
	el: $("#doc"),
	initialize: function(){
		this.render();
	},
	render: function(){
		// Compile template
		var template = _.template( $("#search_template").html(), {} );
		// 將template寫入el中
		this.$el.html( template );
	}
});

var search_view = new SearchView();

View 載入 template(加入動態參數)
HTML

<!-- <%= %> 輸出變數;<%- %> html escape 變數;<% %>程式區塊 -->
<script type="text/template" id="search_template">
	<% alert(123); %>
	<label><%= search_label %></label>
	<input type="text" id="search_input" />
	<input type="button" id="search_button" value="<%- search_value %>" />
</script>

View

var SearchView = Backbone.View.extend({
	el: $("#doc"),
	initialize: function(){
		this.render();
	},
	render: function(){
		// 參數
		var params = {search_label:"TEST",search_value:"搜尋"};
		// Compile template
		var template = _.template( $("#search_template").html(), params);
		// 將template寫入el中
		this.$el.html( template );
	}
});

var search_view = new SearchView();

Router:能針對不同的 fragment 給予相對應的callback function
Router基本操作
HTML:

<a href="#goFacebook">Facebook</a>
<a href="#go/google">Google</a>
<a href="#TEST/TEST/TEST">Yahoo</a>

Javascript

var router = Backbone.Router.extend({
	routes: {
		//按照參數數量分別轉送到不同的Function
		':par1':'fun1',
		':par1/:par2':'fun2',
		//後面為任何字串,若以上不符合,進入到此Function
		'*action':'fun3'
	},
	fun1 : function( par1 ){
		alert("fun1: " + par1);
	},
	fun2 : function( par1, par2){
		alert("fun2: " + par1 + " " + par2 );
	},
	fun3 : function( other ){
		//沒有任何fragment時也會進到這個function
		if( other != '')
			alert("fun3: " + other);
	}
});

//建立router物件
new router();
//啟動Router
Backbone.history.start();

Collection:可以當成Model的陣列
Collenction用法

//建立Model
var Dog = Backbone.Model.extend({
	initialize: function(){
		console.log('New Dog to be born');
	},
	defaults:{
		'name':'Lucky',
		'age':1
	}
});

//建立Collection
var Animals = Backbone.Collection.extend({
	initialize: function() {
		console.log("Animals Collection is initialized");
	},
	//指定存放的類型
	model: Dog,
	//定義排序
	comparator:function(animals1, animals2){
		//用年紀排序(數字大的在前面)
		return animals1.get('age') < animals2.get('age');
	},
	//可以從該url fetch json資料存進Collection
	url:'a.php'
});

var animals = new Animals();
var dog = new Dog();

//新增
animals.add(dog);
animals.add([{'name':'jiajia','age':12},{'name':'black','age':3}]);

//Fetch JSON(需定義URL),會自動存進Collection(會執行reset)
animals.fetch();

//排序(需定義comparator)
animals.sort();

//取出所有Collection裡的特定欄位
console.log( animals.pluck('name') );

//取出姓名叫Lucky的Model
console.log( animals.where({'name':'Lucky'}) );

//Stack
animals.push(dog);
console.log( animals.pop() );

//清空Collection後再存入dog
animals.reset(dog);

//刪除特定物件
animals.remove(dog);

//觸發event
animals.on('add', function(){
	alert('RESET');
});
//alert RESET
animals.add(dog);

//將Collection以JSON格式轉出
console.log( animals.toJSON() );

//按照Collection順序可依index讀取Model
console.log( animals.at(0) );

fetch部份也可以透過success和error參數做一些操作

collection.fetch({
	success:function(collection,response){
		//dosomething
	},
	error:function(collection,response){
		//dosomething
	}
});

其他用法
傳入參數物件

var COLLECTION = Backbone.Collection.extend({
	initialize: function( obj ){
		alert(obj.name);
	}
});
new COLLECTION({name:'Johnson'});

JSONP用法(重新定義fetch)

var COLLECTION = Backbone.Collection.extend({
	url: "http://example.com",
	fetch:function(){
		var self = this;
		var result = $.ajax({
			url:self.url,
			type: "get",
			dataType: "jsonp",
			jsonpCallback : "jsonp_callback",
		});
		result.done(function(res){
			self.reset(res);
			console.log(self.toJSON());
		});
	}
});
var collection = new COLLECTION();
collection.fetch();