蛙蛙推荐:Backbone官方文档翻译
Backbone是一个非常棒的javascript MVC框架,使用它开发web应用,可以让你的客户端代码更少,更清新,更容易维护,更帅,下面是对官方文档的翻译
翻译未完成,而且不是特别的忠实于原文,因为我英语非常的差,所以是按自己的理解来翻译的,看英文没有压力的同学尽量看英文原文,或帮助我一起翻译,谢谢。
Backbone为开发Javascript应用程序提供了一套架构,包括基于健值对儿(attributes)和自定义事件的Model,具有丰富的枚举API(译注:依赖于underscore的集合操作)的Collections,以及可以声明自定义事件处理函数的View,并且可以把这些连接到一个现有的RESTful的JSON接口。
这个项目托管在GitHub上,并且有带有注释的代码,以及在线测试套件,示例和系列指南
您可以在Github的问题页面提交bug或讨论功能,在Freenode #documentcloud频道进行IRC交流,或在google group提出问题,以及发送twitter给@documentcloud
Backbone是DocumentCloud的一个开源组件。
下载和依赖
开发版本 41kb 全部源码及注释
生产环境版本 4.6k 打包并且Gzip压缩
Backone唯一的硬依赖就是Underscore.js,为了让Backbone.Route支持RESTfull持久化和历史以及让Backbone.View来操作Dom,需要包含json2.js,还有jQuery或Zepto.
0.50+更新
我们借此机会澄清一些0.5.0版本里的一些命名。Controller现在叫Router,refresh现在叫reset,以前的saveLocation和setLocation函数,现在用navigate替换了,Backbone.sync方法现在支持jquery.ajax的任何选项了,如果你想使用pushState特性,必须确保调用了History.Start
简介
开发web应用程序时,都会涉及大量的javascript,你要学习的第一件事就是阻止数据直接写在Dom上。用jquery的选择器和回调可以很容易的创建web应用,很直接的操作 DOM,并且很容易的和服务器端数据库之间进行数据同步。但要开发一个富客户端应用则需要一套更有条理的方法。
Backbone里,Models代表你的数据,它可以创建,校验,销毁,以及把数据保存到服务器。每当UI的动作触发了Model的一个属性变化时,Model会引发一个change时间,所有的Views可以在收到事件时呈现自己所包含的Model的数据,或者重新呈现数据。你不需要写胶水代码来通过id来查找dom元素,并手动更新HTML-当Model发生改变,View只需简单的更新自己。
下面的很多例子可以运行。点击“play”按钮可以执行他们。(译注:在这里不能点,到原页面点去)
Backbone.Events
Events是一个可以附加给任何对象的模块,它让对象提供绑定和触发自定义命名事件的能力。Events不需要在绑定前定义,并且可以传递参数,如下。
var object = {};
_.extend(object, Backbone.Events);
object.bind("alert", function(msg) {
alert("Triggered " + msg);
});
object.trigger("alert", "an event");
bind
object.bind(event, callback, [context])
给对象绑定一个callback,callback会在event(根据一个字符串指定)触发时调用,如果你在一个页面上有大量的Event,你可以使用冒号隔开来进行命名空间划分,如poll:start或change:selection
为了给callback调用时提供一个上下文,你可以提供第三个参数,如model.bind('change',this.render, this)
如果一个callback绑定在一个all的事件上,则当任何事件发生时都会被调用,并且回调的第一个参数就是事件名字。下面这个例子是把一个对象的所有事件都代理给另一个对象。
proxy.bind("all", function(eventName) {
object.trigger(eventName);
});
unbind
object.unbind([event], [callback])
移除掉之前绑定在一个对象上的事件处理回调,如果callback没指定,则移除指定事件的所有回调,如果event没指定,则移除该对象上的所有事件。
object.unbind("change", onChange); // Removes just the onChange callback.
object.unbind("change"); // Removes all "change" callbacks.
object.unbind(); // Removes all callbacks on object.
trigger
object.trigger(event, [args])*
触发给定的event的callbacks,指定的args会传递给callbacks。
Backbone.Model
Models是任何Javascript程序的核心,它包括程序的交互式数据以及数据相关的一大部分逻辑:如类型转换,验证,计算属性,访问控制。你可以扩展Backbone.Model来增加领域模型的方法和属性,并提供一个基本的变更(译注:CRUD等)功能。
下面这是一个例子,它定义了一个Model,并增加了自定义方法,设置了属性,绑定了一个特定属性变化事件(change:color)。如果你运行了下面的代码,浏览器侧栏会改变成你输入的颜色。(译注:请到原文地址进行演示)
var Sidebar = Backbone.Model.extend({
promptColor: function() {
var cssColor = prompt("Please enter a CSS color:");
this.set({color: cssColor});
}
});
window.sidebar = new Sidebar;
sidebar.bind('change:color', function(model, color) {
$('#sidebar').css({background: color});
});
sidebar.set({color: 'white'});
sidebar.promptColor();
extend
Backbone.Model.extend(properties, [classProperties])
要创建一个你自己的Model,你需要extend一个Backbone.Model并提供实例属性properties,也可以使用可选的classProperties直接附加在构造函数上。(译注:没用过classProperties)
extend可以正确的设置javascript原型链,你可以继续extend你定义好的Model,子类会自动继承父类的成员,并且可以在子类里覆盖父类成员,实现子类自定义的逻辑。
var Note = Backbone.Model.extend({
initialize: function() { ... },
author: function() { ... },
coordinates: function() { ... },
allowedToEdit: function(account) {
return true;
}
});
var PrivateNote = Note.extend({
allowedToEdit: function(account) {
return account.owns(this);
}
});
javascript没有提供简单的办法调用父类的方法-就是高层的javascript原型链上同名的函数,如果你自己的Model覆盖了Backbone.Model的默认的方法如set,save等,并且你要调用父类的实现,你就必须显式的调用它,如下:
var Note = Backbone.Model.extend({
set: function(attributes, options) {
Backbone.Model.prototype.set.call(this, attributes, options);
...
}
});
constructor/initialize
new Model([attributes])
当你创建一个Model的实例时,你可以通过attributes传递初始值,这些值会被在Model上进行set,如果你的Model定义了一个initialize方法,它会在创建实例时被调用。
new Book({
title: "One Thousand and One Nights",
author: "Scheherazade"
});
get
model.get(attribute)
获取model的指定attribute的当前值,如note.get('title')
set
model.set(attributes, [options])
给model设置一个或多个attribute,如果有attribute的值改变了model的状态,change事件将被触发,除非你通过options参数设置了{silent:tru}。特定attribute的change事件也会触发,所以你只关心特定属性的变化的话,可以只订阅特定的事件,如chagne:title或change:content
note.set({title: "October 12", content: "Lorem Ipsum Dolor Sit Amet..."});
如果model定义了validate方法,当调用set时会先调用该方法,如果验证失败,model的attributes将不会改变,并且set方法会返回false。你可以通过options传递一个error的callback来捕获这种情况,你也可以订阅model的error事件来统一捕获这种验证出错的情况。
escapte
model.escape(attribute)
如果简单的使用get,,则返回原始的attribute,如果你需要把取出的值插入到html里,为了防止XSS攻击,你可以使用escape
var hacker = new Backbone.Model({
name: "<script>alert('xss')</script>"
});
alert(hacker.escape('name'));
has
model.has(attribute)
如果指定的attribute不为null也不会undefined的话返回true。
if (note.has("title")) {
...
}
unset
model.unset(attribute, [options])
在model内部的attributes键值对里删除指定的attribute,并且会触发change事件,除非通过options参数设置了silent。
clear
model.clear([options])
移除model里的所有的attributes,并且会触发change事件,除非通过options设置了silent。
id
model.id
model的一个特殊属性,它可以是任意一个字符串(整数或guid),如果你给model设置了id attribute,它会成为model的一个直接的属性(译注:不需要用get获取)。你可以通过id在collections里查找Model,并且用它来生成model的默认URL(译注:就是model和api交互使用的RESTfull url)。
cid
model.cid
model的一个特殊属性,它是在model第一次在创建时自动分配的一个唯一标示符。当model还没保存到服务器的时候,model还没有id属性,而这时候需要在UI上显示,所以需要一个client id,它们类似c1,c2,c3 ...
attributes
model.attributes
attributes属性用来保存model的内部状态。请使用set来修改它,而不要直接修改它。如果你要获取它,请使用toJSON方法。
defaults
model.defaults or model.defaults()
defaults哈希(或方法)可以给model指定默认的attributes。当创建model的实例时,没有设置的attribute将使用默认值。
var Meal = Backbone.Model.extend({
defaults: {
"appetizer": "caesar salad",
"entree": "ravioli",
"dessert": "cheesecake"
}
});
alert("Dessert will be " + (new Meal).get('dessert'));
请记住,在javascript里,对象是通过引用传递的,所以包含在对象里的默认值,是所有实例共享的
toJSON
model.toJSON()
返回model.attributes的JSON对象副本。它可以用来进行持久化,序列化,或者在view处理model的数据时使用。这个名字不是太好,因为它不是返回一个JSON字符串,但你可以使用JSON.stringify_method)来获取JSON字符串
var artist = new Backbone.Model({
firstName: "Wassily",
lastName: "Kandinsky"
});
artist.set({birthday: "December 16, 1866"});
alert(JSON.stringify(artist));
fetch
model.fetch([options])
通过服务器来重置model的状态。常用于model里还没有任何数据时,或者要保持model里的数据始终是服务器端的最新版本。如果从服务器上拉下的数据和model当前的数据不一样,则会触发change事件。可以在options参数里使用success和error回调函数来处理fetch成功和失败的情况,这两个回调执行时会传入model和response参数。
// Poll every 10 seconds to keep the channel model up-to-date.
setInterval(function() {
channel.fetch();
}, 10000);
save
mode.save([attributes],[options])
通过Backbone.sync把model保存到数据库(或其它的持久层),如果提供了attributes参数,则只保存这里提到的attribute,没提到的attribute不会更新。如果model包含validate方法,且验证失败,那么model不会保存成功。如果model.isNew为true,将会触发create(HTTP POST),如果model已经在服务器存在(译注:model的id已经存在),将触发update(HTTP PUT)
下面这个例子演示了我们重写的Backbone.sync在model第一次save的时候引发create method,而第二次save的时候引发update method.
Backbone.sync = function(method, model) {
alert(method + ": " + JSON.stringify(model));
model.id = 1;
};
var book = new Backbone.Model({
title: "The Rough Riders",
author: "Theodore Roosevelt"
});
book.save();
book.save({author: "Teddy"});
save的第二个options参数里可以设置success和error callback来处理save成功和失败的情况,这两个callback会传入mode和response参数。如果model包含validate且校验失败或服务端返回非200应答,或返回错误的text或JSON应答(译注:比如服务器返回的应答不能parse成JSON)。
book.save({author: "F.D.R."}, {error: function(){ ... }});
destroy
model.destroy([options]) 通过Backbone.sync在服务端销毁model,options参数里可以接受success和error回调。destroy方法会触发model的destroy事件,并且该事件向上冒泡给包含该model的collections
book.destroy({success: function(model, response) {
...
}});
validate
model.validate(attributes)
这是一个默认没定义的方法,我们鼓励你定义它来实现你的自定义验证逻辑。该方法会在调用set和save时执行,并传递要保存或设置的attributes进来。如果这些属性通过了验证,则该方法什么都不要返回,如果验证失败,则可以返回一个字符串或者一个对象(译注:会传道error事件的callback里)。如果验证出错,set和save将不会继续执行,并且会触发error事件。
var Chapter = Backbone.Model.extend({
validate: function(attrs) {
if (attrs.end < attrs.start) {
return "can't end before it starts";
}
}
});
var one = new Chapter({
title : "Chapter One: The Beginning"
});
one.bind("error", function(model, error) {
alert(model.get("title") + " " + error);
});
one.set({
start: 15,
end: 10
});
error事件可以进行比较粗粒度的错误处理,但如果你要再一个view里保存一个model时想显式的处理错误,则可以在save或set方法里直接指定error callback来处理错误及阻止error事件触发。
account.set({access: "unlimited"}, {
error: function(model, error) {
alert(error);
}
});
url
model.url()
返回model在服务器端对应的资源的相对url。如果你的model不用Backbone自动生成的url进行同步,则覆盖该方法实现你自己的逻辑。默认情况下,如果model在collection里,生成的url如/[collection.url]/[model.id],如果model不在collections里,则生成的url如/[urlRoot]/model.id
要通过Collection.url来生成url,确保你定义了它。或者定义urlRoot属性,则所有该model的实例都共享该属性。如果model的id是101,且它所在的Backbone.Collection的url是/document/7/notes,将会生成/documents/7/notes/101
urlRoot
model.urlRoot
如果model不在collection里的话,指定urlRoot来让默认的url方法能够生成类似/[/urlRoot]/id这样的url.
var Book = Backbone.Model.extend({urlRoot : '/books'});
var solaris = new Book({id: "1083-lem-solaris"});
alert(solaris.url());
parse
model.parse(response)
parse在fetch和save时服务端返回数据时调用,该方法传入原始的response对象,你需要返回attribute键值对给model的set方法。该方法默认的实现不做任何操作,简单的返回JSON应答。如果你已经存在一个现有的API不符合model所需要的数据格式,可以覆盖该方法用自定义的逻辑对返回的数据进行转换。(译注:如果要用现有的API,你甚至可以在model里定义sync方法来完全定义特定model的CRUD行为)
(译注:这里略了一些ror的文字)
clone
model.clone()
返回具有相同attributes的model实例。
isNew
mode.isNew()
指示该model是否保存到服务端,如果model还没有id属性,则认为它还没保存到服务端。
change
model.change()
手工触发change事件,如果你之前在set的时候设置了silent:true来阻止触发change事件,你可以在这样多次set后,调用一次change方法来引发一次change事件。
hasChanged
model.hasChanged([attribute])
上次触发change事件后model是否进行了变化,如果指定了attribute,则表示该attribute是否进行了变化。
请注意,此方法一般在如下情况下使用,就是在change的回调里去查看指定的attribute是否发生了变化
book.bind("change", function() {
if (book.hasChanged("title")) {
...
}
});
changeAttributes
model.changeAttributes([attributes])
返回model里进行了变化的attributes,如果指定了attributes参数则返回这些指定的attribute里变化的attribute。这可以得到哪些属性将修改到服务器,以及选择性的向服务器同步数据。
previous
model.previous(attribute)
在change事件回调里,它可以访问指定attribute的旧的值。
var bill = new Backbone.Model({
name: "Bill Smith"
});
bill.bind("change:name", function(model, name) {
alert("Changed name from " + bill.previous("name") + " to " + name);
});
bill.set({name : "Bill Jones"});
previousAttributes
model.previousAttributes()
返回model的变化前的attributes副本,他一般用来比较model的多个版本之间的区别,以及在发生错误的时候把attributes回滚到以前的版本。