[backbone] Getting Started with Backbone.js
一、简介
Backbone 是一个 JavaScript MVC 框架,它属于轻量级框架,且易于学习掌握。
模型、视图、集合和路由器从不同的层面划分了应用程序,并负责处理几种特定事件。
处理 Ajax 应用程序或者 SPI 应用程序时,Backbone 可能是最好的解决方案。
二、详细介绍
Backbone的四大核心组件:
- Model
- Collection
- View
- Controller
Modal
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.
模型是任何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]组成。
例子:
最简定义:表示这个集合的基本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);
}
})
拓展阅读:
1、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.$
2、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
3、backbone的5个小例子
http://arturadib.com/hello-backbonejs/docs/1.html
[backbone] Getting Started with Backbone.js的更多相关文章
- Backbone源码分析-Backbone架构+流程图
作者:nuysoft/高云/nuysoft@gmail.com 声明:本文为原创文章,如需转载,请注明来源并保留原文链接. Backbone0.9.1源码分析分析系列 jQuery1.6.1源码分析系 ...
- Backbone学习笔记一Backbone中的MVC
原文章地址http://bigdots.github.io/2015/12/01/Backbone学习笔记(一)/#more Backbone.js为复杂WEB应用程序提供模型(models).集合( ...
- [转]Backbone.js简单入门范例
本文转自:http://dmyz.org/archives/598 11年刚开始用前端MVC框架时写过一篇文章,当时Knockout和Backbone都在用,但之后的项目全是在用Backbone,主要 ...
- Backbone.js源码分析(珍藏版)
源码分析珍藏,方便下次阅读! // Backbone.js 0.9.2 // (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc. // Backbone ...
- Backbone.js学习之一
昨天一个我崇拜的朋友,徐飞送我一本名为<Backbone.js实战>书,让我心中狂喜,于是带着这份浓厚的兴趣,开始研究Backbone.js之路. 打开这本书的第一句话就很有哲理,“授人以 ...
- 使用backbone.js、zepto.js和trigger.io开发HTML5 App
为了力求运行速度快.响应迅即,我们推荐使用backbone.js和zepto.js. 为了让这个过程更有意思,我们开发了一个小小的示例项目,使用CSS重置样式.Backbone.js和带转场效果的几个 ...
- 网上找的Backbone.js
// Backbone.js 0.9.2 // (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc. // Backbone may be freely ...
- 【 js 基础 】【 源码学习 】源码设计 (更新了backbone分析)
学习源码,除了学习对一些方法的更加聪明的代码实现,同时也要学习源码的设计,把握整体的架构.(推荐对源码有一定熟悉了之后,再看这篇文章) 目录结构:第一部分:zepto 设计分析 第二部分:unders ...
- backbone.js初探(转)
BackBone是JavaScript frameworks for creating MVC-like web applications,最近流行的用来建立单页面web application的工具 ...
随机推荐
- IOS之分析网易新闻存储数据(CoreData的使用,增删改查)
用过网易新闻客户端的朋友们都知道,获取新闻列表时有的时候他会请求网络有时候不会,查看某条新闻的时候再返回会标注已经查看的效果,接下来分析一下是如何实现的. 首先: 1.网易新闻用CoreData存储了 ...
- iOS深入学习(再谈block)
之前写过一篇博客,把Block跟delegate类比,说明了使用block,可以通过更少的代码实现代理的功能.那篇博客将block定义为类的property. 过了这么长时间,对于block的内容有了 ...
- CodeForces 490C Hacking Cypher
Hacking Cypher Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Sub ...
- FZU 2147 A-B Game
A-B Game Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Sta ...
- Java EE 锚、表格用法
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- 在服务器端如何提取checkbox提交的数据?
HttpServeletRequest 单个字符串,getParameters() 多个字符串,getParametersValues(),返回一个数组,需要提前定义一个数组
- Javascript获取地址栏参数值
采用正则表达式获取地址栏参数: function GetQueryString(name) { var reg = new RegExp("(^|&)"+ name +&q ...
- ctrl+z暂停任务
(1) CTRL+Z挂起进程并放入后台 (2) jobs 显示当前暂停的进程 (3) bg %N 使第N个任务在后台运行(%前有空格) (4) fg %N 使第N个任务在前台运行 默认bg,fg不带% ...
- ruby的正则表达式-scan方法
irb(main):001:0> str_vps=%Q{viewpoint_ids: [{"id":"260e053b-d728-4785-888d-eb4f1ca ...
- phpcms 内容——>评论管理 中添加 打开文章链接的 功能
需要实现的功能:在后台管理系统中的 内容 下的——>评论管理 中添加 打开文章链接的 功能 1.数据库表是 v9_comment和v9_comment_data_1. v9_comment是被 ...