Backbone.js教程(初级篇) 这是菜鸟与老油条,屌丝与高富帅的战争 —— 译者:茶几 @chajn 原作者:脱袜子·戴蕾丝 原文:http://backbonetutorials.com/
来源:互联网 发布:交友网站程序源码 编辑:程序博客网 时间:2024/05/17 07:49
Backbone.js教程(初级篇)
这是菜鸟与老油条,屌丝与高富帅的战争 —— 译者:茶几 @chajn
原作者:脱袜子·戴蕾丝 原文:http://backbonetutorials.com/
1. 为啥你需要Backbone.js?
我们知道,仅仅使用jQuery或MooTools啥的来构建web应用或复杂的用户界面是极其困难的。
主要是因为这些JS库都把心思花费在它们擅长做的事情上了,而并没有意识到的是,即便没有任何页面结构,也是可以构建完整的应用的。
用Backbone就可以很容易的把你的应用部署到一个通过jQuery回调的嵌套堆中,然后在页面生成DOM元素实体。
我不需要解释为什么没有结构的页面构建是一个坏主意。
你当然可以每次构造应用的时候都发明一种实现方式,但这只是瞬间的美丽,你错过的是后世的精彩!
那你将永远只能是个屌ser。Balabala……
2. 啥是model?
网络上对MVC的定义是比较尿的,你甚至不知道怎样去理解和怎样去做。
但backbone.js的作者对backbone.js的model表现的定义就很明确。
Models是任何JS应用的核心部分,包括数据交互和众多相关逻辑:格式转换,校验,属性计算,访问控制等。
好的,让我们先创建一个model:
1234567Person = Backbone.Model.extend({
initialize:
function
(){
alert(
"Welcome to this world"
);
}
});
var
person =
new
Person;
-
SO我们看到new一个model的实例后就会触发initialize()函数(models,collections 和 views 的工作机制都是一样滴)。虽然可以不声明initialize,但我们可能会经常用到。
2.1 设置属性
现在我们想设置一些属性,有两种方式,可以在创建model实例时进行传参,也可以在实例生成后通过model.set(obj)来进行设置。
0102030405060708091011Person = Backbone.Model.extend({
initialize:
function
(){
alert(
"Welcome to this world"
);
}
});
var
person =
new
Person({ name:
"Thomas"
, age: 67});
delete
person;
//或者用set,操作等价
var
person =
new
Person();
person.set({ name:
"Thomas"
, age: 67});
-
两种方式在功能上是一样的。有设置属性,就有读取属性,下一步我们来获取它们。
2.2 获取属性
很简单,用 model.get(name)方法就可以读取属性值了。
0102030405060708091011Person = Backbone.Model.extend({
initialize:
function
(){
alert(
"欢迎来到这个二蛋的世界"
);
}
});
var
person =
new
Person({ name:
"Thomas"
, age: 67, children: [
'Ryan'
]});
var
age = person.get(
"age"
);
// 67
var
name = person.get(
"name"
);
// "Thomas"
var
children = person.get(
"children"
);
// ['Ryan']
-
2.3 设置model默认属性
有的时候你可能会想让model有默认属性值。
没的问题,只要在进行model声明的时候设置个'defaults'就行了。
01020304050607080910111213141516Person = Backbone.Model.extend({
defaults: {
name:
'Fetus'
,
age: 0,
children: []
},
initialize:
function
(){
alert(
"欢迎来到这个三蛋的世界"
);
}
});
var
person =
new
Person({ name:
"Thomas"
, age: 67, children: [
'Ryan'
]});
var
age = person.get(
"age"
);
// 67
var
name = person.get(
"name"
);
// "Thomas"
var
children = person.get(
"children"
);
// ['Ryan']
-
2.4 操纵model的属性
Models可以添加自定义方法来进行自身的属性修改,默认这些方法都是公开的。
01020304050607080910111213141516171819Person = Backbone.Model.extend({
defaults: {
name:
'Fetus'
,
age: 0,
children: []
},
initialize:
function
(){
alert(
"欢迎来到这个四蛋的世界"
);
},
adopt:
function
( newChildsName ){
var
children_array =
this
.get(
"children"
);
children_array.push( newChildsName );
this
.set({ children: children_array });
}
});
var
person =
new
Person({ name:
"Thomas"
, age: 67, children: [
'Ryan'
]});
person.adopt(
'John Resig'
);
var
children = person.get(
"children"
);
// ['Ryan', 'John Resig']
-
添加了自定义方法之后,我们就可以更好的控制实例的自身属性了。
2.5 监听model的属性改变
现在说点有用的,我们可以通过model.bind(event,callback)方法来绑定change事件来监听属性改变。
下面的这个例子就是在initialize方法中绑定了一个name属性改变的事件监听。
如果person的name属性改变了,就会弹出个对话框显示新值。
01020304050607080910111213141516171819Person = Backbone.Model.extend({
defaults: {
name:
'Fetus'
,
age: 0,
children: []
},
initialize:
function
(){
alert(
"欢迎来到这个无蛋的世界"
);
this
.bind(
"change:name"
,
function
(){
var
name =
this
.get(
"name"
);
// 'Stewie Griffin'
alert(
"我的名字变为"
+ name );
});
},
replaceNameAttr:
function
( name ){
this
.set({ name: name });
}
});
var
person =
new
Person({ name:
"Thomas"
, age: 67, children: [
'Ryan'
]});
person.replaceNameAttr(
'Stewie Griffin'
);
// 改变后触手会alert()
-
可以单个属性监听,也可以直接监听所有的属性,如:'this.bind("change", function(){});'
2.6 提取,存储和销毁
Models实际上是collection的一部分,用于向服务器请求啥的。
本部分的教程关注的是个体models,咳咳,更多的功能请查看collection部分。
2.7 提示和技巧
2.7.1 获取当前所有的属性
123456var
person =
new
Person({ name:
"Thomas"
, age: 67, children: [
'Ryan'
]});
var
attributes = person.toJSON();
// { name: "Thomas", age: 67, children: ['Ryan']}
/* 返回对当前属性的copy */
delete
attributes;
var
attributes = person.attributes;
/* 上行返回属性的直接引用,对其的任何改变就等于实例属性本身的改变,所以还是建议你使用.set()来进行属性的设置,因为还有backbone的监听呀 */
-
2.7.2 在设置或存储属性的时候进行数据校验
010203040506070809101112131415161718192021222324Person = Backbone.Model.extend({
// 如果从validate中返回字符串了, Backbone就会抛个实例异常
validate:
function
( attributes ){
if
( attributes.age < 0 && attributes.name !=
"Dr Manhatten"
){
return
"你的存在是个错误"
;
}
},
initialize:
function
(){
alert(
"欢迎来到这个报错的世界"
);
this
.bind(
"error"
,
function
(model, error){
// 收到个错误,记录,警告,然后忘记它。╮(‵▽′)╭
alert( error );
});
}
});
var
person =
new
Person;
person.set({ name:
"Mary Poppins"
, age: -1 });
// 会触发error,输出警告
delete
person;
var
person =
new
Person;
person.set({ name:
"Dr Manhatten"
, age: -1 });
// 上帝为何怜悯我们的灵魂,只因为打开的方式不对
-
3. 啥是view?
Backbone的views是用来体现应用的数据模型的。他们还可以用于监听事件。
本部分教程不会说关于views绑定models和collections的事情,重点说一下视图能力和如何使用views与JS模板库,特别是Underscore.js的 _.template。
我们使用jQuery 1.5操作DOM,当然也可以使用其他的库比如MooTools或Sizzle,但Backbone.js的官方文档说支持使用jQuery。
咳咳,也就是说Backbone.View事件在jQuery以外的库中可能无法使用。
好我们开始,这回我们要实现一个搜索框。
123456789SearchView = Backbone.View.extend({
initialize:
function
(){
alert(
"Alerts suck."
);
}
});
// The initialize function is always called when instantiating a Backbone View.
// Consider it the constructor of the class.
var
search_view =
new
SearchView;
-
3.1 “el”属性
“el”属性引用DOM对象。每个Backbone.js的view都会有个“el”属性。
如果没定义的话它会默认创建一个空的div元素。
来让我们设置个div#search_container到el属性上去,以保证这个Backbone.View是有效的。
0102030405060708091011<
div
id
=
"search_container"
></
div
>
<
script
type
=
"text/javascript"
>
SearchView = Backbone.View.extend({
initialize: function(){
alert("Alerts suck.");
}
});
var search_view = new SearchView({ el: $("#search_container") });
</
script
>
-
注意:既然是绑定在了这个容器元素了,那就代表着所有的事件都是以此DOM元素为基础而触发的噢。
3.2 模板加载
Backbone.js是依赖于Underscore.js的,因为它包括micro-templating方案。
更多信息请参考Underscore.js'的官方文档去。
让我们实现一个“render()”方法进行视图初始化,“render()”方法会用jQuery加载我们的模板到“el”属性的容器中。
0102030405060708091011121314151617181920212223<
div
id
=
"search_container"
></
div
>
<
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
>
<
script
type
=
"text/javascript"
>
SearchView = Backbone.View.extend({
initialize: function(){
this.render();
},
render: function(){
// Compile the template using underscore
var template = _.template( $("#search_template").html(), {} );
// Load the compiled HTML into the Backbone "el"
this.el.html( template );
}
});
var search_view = new SearchView({ el: $("#search_container") });
</
script
>
-
提示:可以将你的模板放到CDN中的单独文件里,这样用户使用就不用每次都下载了。
3.3 事件监听
在view加一个监听,可以用Backbone.View的“events”属性。
要记得,事件监听只能绑定到“el”属性的子元素中。
让我们绑定个“click”事件到按钮上去。
01020304050607080910111213141516171819202122232425262728<
div
id
=
"search_container"
></
div
>
<
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
>
<
script
type
=
"text/javascript"
>
SearchView = Backbone.View.extend({
initialize: function(){
this.render();
},
render: function(){
var template = _.template( $("#search_template").html(), {} );
this.el.html( template );
},
events: {
"click input[type=button]": "doSearch"
},
doSearch: function( event ){
// Button clicked, you can access the element that was clicked with event.currentTarget
alert( "Search for " + $("#search_input").val() );
}
});
var search_view = new SearchView({ el: $("#search_container") });
</
script
>
-
3.4 提示和技巧
3.4.1 使用模板变量
010203040506070809101112131415161718192021222324252627282930313233<
div
id
=
"search_container"
></
div
>
<
script
type
=
"text/template"
id
=
"search_template"
>
<!-- Access template variables with <%= %> -->
<
label
><%= search_label %></
label
>
<
input
type
=
"text"
id
=
"search_input"
/>
<
input
type
=
"button"
id
=
"search_button"
value
=
"Search"
/>
</
script
>
<
script
type
=
"text/javascript"
>
SearchView = Backbone.View.extend({
initialize: function(){
this.render();
},
render: function(){
//Pass variables in using Underscore.js Template
var variables = { search_label: "My Search" };
// Compile the template using underscore
var template = _.template( $("#search_template").html(), variables );
// Load the compiled HTML into the Backbone "el"
this.el.html( template );
},
events: {
"click input[type=button]": "doSearch"
},
doSearch: function( event ){
// Button clicked, you can access the element that was clicked with event.currentTarget
alert( "Search for " + $("#search_input").val() );
}
});
var search_view = new SearchView({ el: $("#search_container") });
</
script
>
-
4. 啥是collection?
Backbone的collections其实就是个有序的models集合。适用于以下情况;
Model: Student, Collection: ClassStudents
Model: Todo Item, Collection: Todo List
Model: Animals, Collection: Zoo
通常你的collection可能只用一个类型的model,但是models并不局限于某一类型的collection;
Model: Student, Collection: Gym Class
Model: Student, Collection: Art Class
Model: Student, Collection: English Class
关于Model/Collection,这里有一个通用的例子。
123456789var
Song = Backbone.Model.extend({
initialize:
function
(){
console.log(
"Music is the answer"
);
}
});
var
Album = Backbone.Collection.extend({
model: Song
});
-
4.1 构建 collection
现在我们来点实在的,下面的例子演示了collection的使用方法。
0102030405060708091011121314151617181920var
Song = Backbone.Model.extend({
defaults: {
name:
"Not specified"
,
artist:
"Not specified"
},
initialize:
function
(){
console.log(
"Music is the answer"
);
}
});
var
Album = Backbone.Collection.extend({
model: Song
});
var
song1 =
new
Song({ name:
"How Bizarre"
, artist:
"OMC"
});
var
song2 =
new
Song({ name:
"Sexual Healing"
, artist:
"Marvin Gaye"
});
var
song3 =
new
Song({ name:
"Talk It Over In Bed"
, artist:
"OMC"
});
var
myAlbum =
new
Album([ song1, song2, song3]);
console.log( myAlbum.models );
// [song1, song2, song3]
-
5. 啥是router?
12345//@注1:本章的所有实例都是在http://example.com顶级域名下实现的。
//如果是http://example.com/tset/test.html的形式,则路径标记#前不能加/。
//如:http://example.com/#/user/helphttp://example.com/test/test.html#/user/help
//@注2:Backbone.js 0.9.2 的取路径后的值是posts/12,匹配^/posts/([^/]+)$不能(/posts/:id转换后的正则表达式)。所以原参数要改为posts/:id,测试才能通过。
//以下有错误的地方标红不改,以此类推。
-
Backbone的routers其实就相当于你的应用URL的hash(#)。
如果你读过“啥是view?”,那你应该知道,他们并不符合传统的MVC语义,本章将会详细解释这一点。
尽管Backbone的“router”对任何程序和功能都很有用,但它需要URL的routing/history功能。
Routers的定义包括路径和映射函数,下面的例子就让我们定义一个路径。
还请注意,routes只解析url的“#”之后的标记。
你的应用的所有链接都应该是像“#/action”或“#action”这样。
(附加个斜杠看起来会更好一些,比如:http://example.com/#/user/help)
0102030405060708091011121314151617181920<script>
var
AppRouter = Backbone.Router.extend({
routes: {
"*actions"
:
"defaultRoute"
// matcheshttp://example.com/#anything-here
},
defaultRoute:
function
( actions ){
// The variable passed in matches the variable in the route definition "actions"
alert( actions );
}
});
// Initiate the router
var
app_router =
new
AppRouter;
// Start Backbone history a neccesary step for bookmarkable URL's
Backbone.history.start();
</script>
_URL进行变化_
[Activate route](
#action)
[Activate another route](
#/route/action)
-
请注意:Backbone 0.5 (released 1. July 2011)之前的版本,Router被称作Controller。为了避免字义混淆,Backbone的开发人员把名字改成Router了。
因此,如果你发现自己使用了Backbone的一个旧版本,那你应该写Backbone.Controller.extend({ ** });
5.1 动态Routing
原始框架允许你的routes定义包含动静混合态路径参数。
例如,你可能想进行检索一个post的id,你的URL看起来可能会是“http://example.com/#/posts/12”。
一旦这个路径被激活,你就可以取到id的值并做相应的处理了。下面是这个例子的实现。
010203040506070809101112131415161718192021222324<script>
var
AppRouter = Backbone.Router.extend({
routes: {
"/posts/:id"
:
"getPost"
,
//@注2
"*actions"
:
"defaultRoute"
// Backbone will try match the route above first
},
getPost:
function
( id ) {
// Note the variable in the route definition being passed in here
alert(
"Get post number "
+ id );
},
defaultRoute:
function
( actions ){
alert( actions );
}
});
// Instantiate the router
var
app_router =
new
AppRouter;
// Start Backbone history a neccesary step for bookmarkable URL's
Backbone.history.start();
</script>
_URL进行改变_
[Post 120](
#/posts/120)
[Post 130](
#/posts/130)
-
5.2 动态路径对比——":params"和"*splats"
Backbone使用两种参数模式实现路径,第一种是":params"匹配URL路径内任何斜杠之间的字符串,而还有一种是"splats"匹配任意数量的URL路径。
注意"splat"的本质意思,他总是最后一个变量,因为它匹配的是URL路径之后的全部内容。
在route中定义的任何"*splats"或":params"都会以参数的形式穿入关联函数中。
比如一个route定义了"/:route/:action",那就会传入两个参数(“route”和“action”) 到回调函数中。
下面的示例使用":params"和"*splats"。
010203040506070809101112131415161718routes: {
"/posts/:id"
:
"getPost"
,
//@注2,下同
// <a href="http://example.com/#/posts/121">Example</a>
"/download/*path"
:
"downloadFile"
,
// <a href="http://example.com/#/download/user/images/hey.gif">Download</a>
"/:route/:action"
:
"loadView"
,
// <a href="http://example.com/#/dashboard/graph">LoadRoute/Action View</a>
},
getPost:
function
( id ){
alert(id);
// 121
},
downloadFile:
function
( path ){
alert(path);
// user/images/hey.gif
},
loadView:
function
( route, action ){
alert(route +
"_"
+ action);
// dashboard_graph
}
-
这是菜鸟与老油条,屌丝与高富帅的战争 —— 译者:茶几 @chajn
原作者:脱袜子·戴蕾丝 原文:http://backbonetutorials.com/
1. 为啥你需要Backbone.js?
我们知道,仅仅使用jQuery或MooTools啥的来构建web应用或复杂的用户界面是极其困难的。
主要是因为这些JS库都把心思花费在它们擅长做的事情上了,而并没有意识到的是,即便没有任何页面结构,也是可以构建完整的应用的。
用Backbone就可以很容易的把你的应用部署到一个通过jQuery回调的嵌套堆中,然后在页面生成DOM元素实体。
我不需要解释为什么没有结构的页面构建是一个坏主意。
你当然可以每次构造应用的时候都发明一种实现方式,但这只是瞬间的美丽,你错过的是后世的精彩!
那你将永远只能是个屌ser。Balabala……
2. 啥是model?
网络上对MVC的定义是比较尿的,你甚至不知道怎样去理解和怎样去做。
但backbone.js的作者对backbone.js的model表现的定义就很明确。
Models是任何JS应用的核心部分,包括数据交互和众多相关逻辑:格式转换,校验,属性计算,访问控制等。
好的,让我们先创建一个model:
Person = Backbone.Model.extend({
initialize:
function
(){
alert(
"Welcome to this world"
);
}
});
var
person =
new
Person;
-
SO我们看到new一个model的实例后就会触发initialize()函数(models,collections 和 views 的工作机制都是一样滴)。虽然可以不声明initialize,但我们可能会经常用到。
2.1 设置属性
现在我们想设置一些属性,有两种方式,可以在创建model实例时进行传参,也可以在实例生成后通过model.set(obj)来进行设置。
Person = Backbone.Model.extend({
initialize:
function
(){
alert(
"Welcome to this world"
);
}
});
var
person =
new
Person({ name:
"Thomas"
, age: 67});
delete
person;
//或者用set,操作等价
var
person =
new
Person();
person.set({ name:
"Thomas"
, age: 67});
-
两种方式在功能上是一样的。有设置属性,就有读取属性,下一步我们来获取它们。
2.2 获取属性
很简单,用 model.get(name)方法就可以读取属性值了。
Person = Backbone.Model.extend({
initialize:
function
(){
alert(
"欢迎来到这个二蛋的世界"
);
}
});
var
person =
new
Person({ name:
"Thomas"
, age: 67, children: [
'Ryan'
]});
var
age = person.get(
"age"
);
// 67
var
name = person.get(
"name"
);
// "Thomas"
var
children = person.get(
"children"
);
// ['Ryan']
-
2.3 设置model默认属性
有的时候你可能会想让model有默认属性值。
没的问题,只要在进行model声明的时候设置个'defaults'就行了。
Person = Backbone.Model.extend({
defaults: {
name:
'Fetus'
,
age: 0,
children: []
},
initialize:
function
(){
alert(
"欢迎来到这个三蛋的世界"
);
}
});
var
person =
new
Person({ name:
"Thomas"
, age: 67, children: [
'Ryan'
]});
var
age = person.get(
"age"
);
// 67
var
name = person.get(
"name"
);
// "Thomas"
var
children = person.get(
"children"
);
// ['Ryan']
-
2.4 操纵model的属性
Models可以添加自定义方法来进行自身的属性修改,默认这些方法都是公开的。
Person = Backbone.Model.extend({
defaults: {
name:
'Fetus'
,
age: 0,
children: []
},
initialize:
function
(){
alert(
"欢迎来到这个四蛋的世界"
);
},
adopt:
function
( newChildsName ){
var
children_array =
this
.get(
"children"
);
children_array.push( newChildsName );
this
.set({ children: children_array });
}
});
var
person =
new
Person({ name:
"Thomas"
, age: 67, children: [
'Ryan'
]});
person.adopt(
'John Resig'
);
var
children = person.get(
"children"
);
// ['Ryan', 'John Resig']
-
添加了自定义方法之后,我们就可以更好的控制实例的自身属性了。
2.5 监听model的属性改变
现在说点有用的,我们可以通过model.bind(event,callback)方法来绑定change事件来监听属性改变。
下面的这个例子就是在initialize方法中绑定了一个name属性改变的事件监听。
如果person的name属性改变了,就会弹出个对话框显示新值。
Person = Backbone.Model.extend({
defaults: {
name:
'Fetus'
,
age: 0,
children: []
},
initialize:
function
(){
alert(
"欢迎来到这个无蛋的世界"
);
this
.bind(
"change:name"
,
function
(){
var
name =
this
.get(
"name"
);
// 'Stewie Griffin'
alert(
"我的名字变为"
+ name );
});
},
replaceNameAttr:
function
( name ){
this
.set({ name: name });
}
});
var
person =
new
Person({ name:
"Thomas"
, age: 67, children: [
'Ryan'
]});
person.replaceNameAttr(
'Stewie Griffin'
);
// 改变后触手会alert()
-
可以单个属性监听,也可以直接监听所有的属性,如:'this.bind("change", function(){});'
2.6 提取,存储和销毁
Models实际上是collection的一部分,用于向服务器请求啥的。
本部分的教程关注的是个体models,咳咳,更多的功能请查看collection部分。
2.7 提示和技巧
2.7.1 获取当前所有的属性
var
person =
new
Person({ name:
"Thomas"
, age: 67, children: [
'Ryan'
]});
var
attributes = person.toJSON();
// { name: "Thomas", age: 67, children: ['Ryan']}
/* 返回对当前属性的copy */
delete
attributes;
var
attributes = person.attributes;
/* 上行返回属性的直接引用,对其的任何改变就等于实例属性本身的改变,所以还是建议你使用.set()来进行属性的设置,因为还有backbone的监听呀 */
-
2.7.2 在设置或存储属性的时候进行数据校验
Person = Backbone.Model.extend({
// 如果从validate中返回字符串了, Backbone就会抛个实例异常
validate:
function
( attributes ){
if
( attributes.age < 0 && attributes.name !=
"Dr Manhatten"
){
return
"你的存在是个错误"
;
}
},
initialize:
function
(){
alert(
"欢迎来到这个报错的世界"
);
this
.bind(
"error"
,
function
(model, error){
// 收到个错误,记录,警告,然后忘记它。╮(‵▽′)╭
alert( error );
});
}
});
var
person =
new
Person;
person.set({ name:
"Mary Poppins"
, age: -1 });
// 会触发error,输出警告
delete
person;
var
person =
new
Person;
person.set({ name:
"Dr Manhatten"
, age: -1 });
// 上帝为何怜悯我们的灵魂,只因为打开的方式不对
-
3. 啥是view?
Backbone的views是用来体现应用的数据模型的。他们还可以用于监听事件。
本部分教程不会说关于views绑定models和collections的事情,重点说一下视图能力和如何使用views与JS模板库,特别是Underscore.js的 _.template。
我们使用jQuery 1.5操作DOM,当然也可以使用其他的库比如MooTools或Sizzle,但Backbone.js的官方文档说支持使用jQuery。
咳咳,也就是说Backbone.View事件在jQuery以外的库中可能无法使用。
好我们开始,这回我们要实现一个搜索框。
SearchView = Backbone.View.extend({
initialize:
function
(){
alert(
"Alerts suck."
);
}
});
// The initialize function is always called when instantiating a Backbone View.
// Consider it the constructor of the class.
var
search_view =
new
SearchView;
-
3.1 “el”属性
“el”属性引用DOM对象。每个Backbone.js的view都会有个“el”属性。
如果没定义的话它会默认创建一个空的div元素。
来让我们设置个div#search_container到el属性上去,以保证这个Backbone.View是有效的。
<
div
id
=
"search_container"
></
div
>
<
script
type
=
"text/javascript"
>
SearchView = Backbone.View.extend({
initialize: function(){
alert("Alerts suck.");
}
});
var search_view = new SearchView({ el: $("#search_container") });
</
script
>
-
注意:既然是绑定在了这个容器元素了,那就代表着所有的事件都是以此DOM元素为基础而触发的噢。
3.2 模板加载
Backbone.js是依赖于Underscore.js的,因为它包括micro-templating方案。
更多信息请参考Underscore.js'的官方文档去。
让我们实现一个“render()”方法进行视图初始化,“render()”方法会用jQuery加载我们的模板到“el”属性的容器中。
<
div
id
=
"search_container"
></
div
>
<
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
>
<
script
type
=
"text/javascript"
>
SearchView = Backbone.View.extend({
initialize: function(){
this.render();
},
render: function(){
// Compile the template using underscore
var template = _.template( $("#search_template").html(), {} );
// Load the compiled HTML into the Backbone "el"
this.el.html( template );
}
});
var search_view = new SearchView({ el: $("#search_container") });
</
script
>
-
提示:可以将你的模板放到CDN中的单独文件里,这样用户使用就不用每次都下载了。
3.3 事件监听
在view加一个监听,可以用Backbone.View的“events”属性。
要记得,事件监听只能绑定到“el”属性的子元素中。
让我们绑定个“click”事件到按钮上去。
<
div
id
=
"search_container"
></
div
>
<
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
>
<
script
type
=
"text/javascript"
>
SearchView = Backbone.View.extend({
initialize: function(){
this.render();
},
render: function(){
var template = _.template( $("#search_template").html(), {} );
this.el.html( template );
},
events: {
"click input[type=button]": "doSearch"
},
doSearch: function( event ){
// Button clicked, you can access the element that was clicked with event.currentTarget
alert( "Search for " + $("#search_input").val() );
}
});
var search_view = new SearchView({ el: $("#search_container") });
</
script
>
-
3.4 提示和技巧
3.4.1 使用模板变量
<
div
id
=
"search_container"
></
div
>
<
script
type
=
"text/template"
id
=
"search_template"
>
<!-- Access template variables with <%= %> -->
<
label
><%= search_label %></
label
>
<
input
type
=
"text"
id
=
"search_input"
/>
<
input
type
=
"button"
id
=
"search_button"
value
=
"Search"
/>
</
script
>
<
script
type
=
"text/javascript"
>
SearchView = Backbone.View.extend({
initialize: function(){
this.render();
},
render: function(){
//Pass variables in using Underscore.js Template
var variables = { search_label: "My Search" };
// Compile the template using underscore
var template = _.template( $("#search_template").html(), variables );
// Load the compiled HTML into the Backbone "el"
this.el.html( template );
},
events: {
"click input[type=button]": "doSearch"
},
doSearch: function( event ){
// Button clicked, you can access the element that was clicked with event.currentTarget
alert( "Search for " + $("#search_input").val() );
}
});
var search_view = new SearchView({ el: $("#search_container") });
</
script
>
-
4. 啥是collection?
Backbone的collections其实就是个有序的models集合。适用于以下情况;
Model: Student, Collection: ClassStudents
Model: Todo Item, Collection: Todo List
Model: Animals, Collection: Zoo
通常你的collection可能只用一个类型的model,但是models并不局限于某一类型的collection;
Model: Student, Collection: Gym Class
Model: Student, Collection: Art Class
Model: Student, Collection: English Class
关于Model/Collection,这里有一个通用的例子。
var
Song = Backbone.Model.extend({
initialize:
function
(){
console.log(
"Music is the answer"
);
}
});
var
Album = Backbone.Collection.extend({
model: Song
});
-
4.1 构建 collection
现在我们来点实在的,下面的例子演示了collection的使用方法。
var
Song = Backbone.Model.extend({
defaults: {
name:
"Not specified"
,
artist:
"Not specified"
},
initialize:
function
(){
console.log(
"Music is the answer"
);
}
});
var
Album = Backbone.Collection.extend({
model: Song
});
var
song1 =
new
Song({ name:
"How Bizarre"
, artist:
"OMC"
});
var
song2 =
new
Song({ name:
"Sexual Healing"
, artist:
"Marvin Gaye"
});
var
song3 =
new
Song({ name:
"Talk It Over In Bed"
, artist:
"OMC"
});
var
myAlbum =
new
Album([ song1, song2, song3]);
console.log( myAlbum.models );
// [song1, song2, song3]
-
5. 啥是router?
//@注1:本章的所有实例都是在http://example.com顶级域名下实现的。
//如果是http://example.com/tset/test.html的形式,则路径标记#前不能加/。
//如:http://example.com/#/user/helphttp://example.com/test/test.html#/user/help
//@注2:Backbone.js 0.9.2 的取路径后的值是posts/12,匹配^/posts/([^/]+)$不能(/posts/:id转换后的正则表达式)。所以原参数要改为posts/:id,测试才能通过。
//以下有错误的地方标红不改,以此类推。
-
Backbone的routers其实就相当于你的应用URL的hash(#)。
如果你读过“啥是view?”,那你应该知道,他们并不符合传统的MVC语义,本章将会详细解释这一点。
尽管Backbone的“router”对任何程序和功能都很有用,但它需要URL的routing/history功能。
Routers的定义包括路径和映射函数,下面的例子就让我们定义一个路径。
还请注意,routes只解析url的“#”之后的标记。
你的应用的所有链接都应该是像“#/action”或“#action”这样。
(附加个斜杠看起来会更好一些,比如:http://example.com/#/user/help)
<script>
var
AppRouter = Backbone.Router.extend({
routes: {
"*actions"
:
"defaultRoute"
// matcheshttp://example.com/#anything-here
},
defaultRoute:
function
( actions ){
// The variable passed in matches the variable in the route definition "actions"
alert( actions );
}
});
// Initiate the router
var
app_router =
new
AppRouter;
// Start Backbone history a neccesary step for bookmarkable URL's
Backbone.history.start();
</script>
_URL进行变化_
[Activate route](
#action)
[Activate another route](
#/route/action)
-
请注意:Backbone 0.5 (released 1. July 2011)之前的版本,Router被称作Controller。为了避免字义混淆,Backbone的开发人员把名字改成Router了。
因此,如果你发现自己使用了Backbone的一个旧版本,那你应该写Backbone.Controller.extend({ ** });
5.1 动态Routing
原始框架允许你的routes定义包含动静混合态路径参数。
例如,你可能想进行检索一个post的id,你的URL看起来可能会是“http://example.com/#/posts/12”。
一旦这个路径被激活,你就可以取到id的值并做相应的处理了。下面是这个例子的实现。
<script>
var
AppRouter = Backbone.Router.extend({
routes: {
"/posts/:id"
:
"getPost"
,
//@注2
"*actions"
:
"defaultRoute"
// Backbone will try match the route above first
},
getPost:
function
( id ) {
// Note the variable in the route definition being passed in here
alert(
"Get post number "
+ id );
},
defaultRoute:
function
( actions ){
alert( actions );
}
});
// Instantiate the router
var
app_router =
new
AppRouter;
// Start Backbone history a neccesary step for bookmarkable URL's
Backbone.history.start();
</script>
_URL进行改变_
[Post 120](
#/posts/120)
[Post 130](
#/posts/130)
-
5.2 动态路径对比——":params"和"*splats"
Backbone使用两种参数模式实现路径,第一种是":params"匹配URL路径内任何斜杠之间的字符串,而还有一种是"splats"匹配任意数量的URL路径。
注意"splat"的本质意思,他总是最后一个变量,因为它匹配的是URL路径之后的全部内容。
在route中定义的任何"*splats"或":params"都会以参数的形式穿入关联函数中。
比如一个route定义了"/:route/:action",那就会传入两个参数(“route”和“action”) 到回调函数中。
下面的示例使用":params"和"*splats"。
routes: {
"/posts/:id"
:
"getPost"
,
//@注2,下同
// <a href="http://example.com/#/posts/121">Example</a>
"/download/*path"
:
"downloadFile"
,
// <a href="http://example.com/#/download/user/images/hey.gif">Download</a>
"/:route/:action"
:
"loadView"
,
// <a href="http://example.com/#/dashboard/graph">LoadRoute/Action View</a>
},
getPost:
function
( id ){
alert(id);
// 121
},
downloadFile:
function
( path ){
alert(path);
// user/images/hey.gif
},
loadView:
function
( route, action ){
alert(route +
"_"
+ action);
// dashboard_graph
}
-
这是菜鸟与老油条,屌丝与高富帅的战争 —— 译者:茶几 @chajn
原作者:脱袜子·戴蕾丝 原文:http://backbonetutorials.com/
1. 为啥你需要Backbone.js?
我们知道,仅仅使用jQuery或MooTools啥的来构建web应用或复杂的用户界面是极其困难的。
主要是因为这些JS库都把心思花费在它们擅长做的事情上了,而并没有意识到的是,即便没有任何页面结构,也是可以构建完整的应用的。
用Backbone就可以很容易的把你的应用部署到一个通过jQuery回调的嵌套堆中,然后在页面生成DOM元素实体。
我不需要解释为什么没有结构的页面构建是一个坏主意。
你当然可以每次构造应用的时候都发明一种实现方式,但这只是瞬间的美丽,你错过的是后世的精彩!
那你将永远只能是个屌ser。Balabala……
2. 啥是model?
网络上对MVC的定义是比较尿的,你甚至不知道怎样去理解和怎样去做。
但backbone.js的作者对backbone.js的model表现的定义就很明确。
Models是任何JS应用的核心部分,包括数据交互和众多相关逻辑:格式转换,校验,属性计算,访问控制等。
好的,让我们先创建一个model:
Person = Backbone.Model.extend({
initialize:
function
(){
alert(
"Welcome to this world"
);
}
});
var
person =
new
Person;
-
SO我们看到new一个model的实例后就会触发initialize()函数(models,collections 和 views 的工作机制都是一样滴)。虽然可以不声明initialize,但我们可能会经常用到。
2.1 设置属性
现在我们想设置一些属性,有两种方式,可以在创建model实例时进行传参,也可以在实例生成后通过model.set(obj)来进行设置。
Person = Backbone.Model.extend({
initialize:
function
(){
alert(
"Welcome to this world"
);
}
});
var
person =
new
Person({ name:
"Thomas"
, age: 67});
delete
person;
//或者用set,操作等价
var
person =
new
Person();
person.set({ name:
"Thomas"
, age: 67});
-
两种方式在功能上是一样的。有设置属性,就有读取属性,下一步我们来获取它们。
2.2 获取属性
很简单,用 model.get(name)方法就可以读取属性值了。
Person = Backbone.Model.extend({
initialize:
function
(){
alert(
"欢迎来到这个二蛋的世界"
);
}
});
var
person =
new
Person({ name:
"Thomas"
, age: 67, children: [
'Ryan'
]});
var
age = person.get(
"age"
);
// 67
var
name = person.get(
"name"
);
// "Thomas"
var
children = person.get(
"children"
);
// ['Ryan']
-
2.3 设置model默认属性
有的时候你可能会想让model有默认属性值。
没的问题,只要在进行model声明的时候设置个'defaults'就行了。
Person = Backbone.Model.extend({
defaults: {
name:
'Fetus'
,
age: 0,
children: []
},
initialize:
function
(){
alert(
"欢迎来到这个三蛋的世界"
);
}
});
var
person =
new
Person({ name:
"Thomas"
, age: 67, children: [
'Ryan'
]});
var
age = person.get(
"age"
);
// 67
var
name = person.get(
"name"
);
// "Thomas"
var
children = person.get(
"children"
);
// ['Ryan']
-
2.4 操纵model的属性
Models可以添加自定义方法来进行自身的属性修改,默认这些方法都是公开的。
Person = Backbone.Model.extend({
defaults: {
name:
'Fetus'
,
age: 0,
children: []
},
initialize:
function
(){
alert(
"欢迎来到这个四蛋的世界"
);
},
adopt:
function
( newChildsName ){
var
children_array =
this
.get(
"children"
);
children_array.push( newChildsName );
this
.set({ children: children_array });
}
});
var
person =
new
Person({ name:
"Thomas"
, age: 67, children: [
'Ryan'
]});
person.adopt(
'John Resig'
);
var
children = person.get(
"children"
);
// ['Ryan', 'John Resig']
-
添加了自定义方法之后,我们就可以更好的控制实例的自身属性了。
2.5 监听model的属性改变
现在说点有用的,我们可以通过model.bind(event,callback)方法来绑定change事件来监听属性改变。
下面的这个例子就是在initialize方法中绑定了一个name属性改变的事件监听。
如果person的name属性改变了,就会弹出个对话框显示新值。
Person = Backbone.Model.extend({
defaults: {
name:
'Fetus'
,
age: 0,
children: []
},
initialize:
function
(){
alert(
"欢迎来到这个无蛋的世界"
);
this
.bind(
"change:name"
,
function
(){
var
name =
this
.get(
"name"
);
// 'Stewie Griffin'
alert(
"我的名字变为"
+ name );
});
},
replaceNameAttr:
function
( name ){
this
.set({ name: name });
}
});
var
person =
new
Person({ name:
"Thomas"
, age: 67, children: [
'Ryan'
]});
person.replaceNameAttr(
'Stewie Griffin'
);
// 改变后触手会alert()
-
可以单个属性监听,也可以直接监听所有的属性,如:'this.bind("change", function(){});'
2.6 提取,存储和销毁
Models实际上是collection的一部分,用于向服务器请求啥的。
本部分的教程关注的是个体models,咳咳,更多的功能请查看collection部分。
2.7 提示和技巧
2.7.1 获取当前所有的属性
var
person =
new
Person({ name:
"Thomas"
, age: 67, children: [
'Ryan'
]});
var
attributes = person.toJSON();
// { name: "Thomas", age: 67, children: ['Ryan']}
/* 返回对当前属性的copy */
delete
attributes;
var
attributes = person.attributes;
/* 上行返回属性的直接引用,对其的任何改变就等于实例属性本身的改变,所以还是建议你使用.set()来进行属性的设置,因为还有backbone的监听呀 */
-
2.7.2 在设置或存储属性的时候进行数据校验
Person = Backbone.Model.extend({
// 如果从validate中返回字符串了, Backbone就会抛个实例异常
validate:
function
( attributes ){
if
( attributes.age < 0 && attributes.name !=
"Dr Manhatten"
){
return
"你的存在是个错误"
;
}
},
initialize:
function
(){
alert(
"欢迎来到这个报错的世界"
);
this
.bind(
"error"
,
function
(model, error){
// 收到个错误,记录,警告,然后忘记它。╮(‵▽′)╭
alert( error );
});
}
});
var
person =
new
Person;
person.set({ name:
"Mary Poppins"
, age: -1 });
// 会触发error,输出警告
delete
person;
var
person =
new
Person;
person.set({ name:
"Dr Manhatten"
, age: -1 });
// 上帝为何怜悯我们的灵魂,只因为打开的方式不对
-
3. 啥是view?
Backbone的views是用来体现应用的数据模型的。他们还可以用于监听事件。
本部分教程不会说关于views绑定models和collections的事情,重点说一下视图能力和如何使用views与JS模板库,特别是Underscore.js的 _.template。
我们使用jQuery 1.5操作DOM,当然也可以使用其他的库比如MooTools或Sizzle,但Backbone.js的官方文档说支持使用jQuery。
咳咳,也就是说Backbone.View事件在jQuery以外的库中可能无法使用。
好我们开始,这回我们要实现一个搜索框。
SearchView = Backbone.View.extend({
initialize:
function
(){
alert(
"Alerts suck."
);
}
});
// The initialize function is always called when instantiating a Backbone View.
// Consider it the constructor of the class.
var
search_view =
new
SearchView;
-
3.1 “el”属性
“el”属性引用DOM对象。每个Backbone.js的view都会有个“el”属性。
如果没定义的话它会默认创建一个空的div元素。
来让我们设置个div#search_container到el属性上去,以保证这个Backbone.View是有效的。
<
div
id
=
"search_container"
></
div
>
<
script
type
=
"text/javascript"
>
SearchView = Backbone.View.extend({
initialize: function(){
alert("Alerts suck.");
}
});
var search_view = new SearchView({ el: $("#search_container") });
</
script
>
-
注意:既然是绑定在了这个容器元素了,那就代表着所有的事件都是以此DOM元素为基础而触发的噢。
3.2 模板加载
Backbone.js是依赖于Underscore.js的,因为它包括micro-templating方案。
更多信息请参考Underscore.js'的官方文档去。
让我们实现一个“render()”方法进行视图初始化,“render()”方法会用jQuery加载我们的模板到“el”属性的容器中。
<
div
id
=
"search_container"
></
div
>
<
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
>
<
script
type
=
"text/javascript"
>
SearchView = Backbone.View.extend({
initialize: function(){
this.render();
},
render: function(){
// Compile the template using underscore
var template = _.template( $("#search_template").html(), {} );
// Load the compiled HTML into the Backbone "el"
this.el.html( template );
}
});
var search_view = new SearchView({ el: $("#search_container") });
</
script
>
-
提示:可以将你的模板放到CDN中的单独文件里,这样用户使用就不用每次都下载了。
3.3 事件监听
在view加一个监听,可以用Backbone.View的“events”属性。
要记得,事件监听只能绑定到“el”属性的子元素中。
让我们绑定个“click”事件到按钮上去。
<
div
id
=
"search_container"
></
div
>
<
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
>
<
script
type
=
"text/javascript"
>
SearchView = Backbone.View.extend({
initialize: function(){
this.render();
},
render: function(){
var template = _.template( $("#search_template").html(), {} );
this.el.html( template );
},
events: {
"click input[type=button]": "doSearch"
},
doSearch: function( event ){
// Button clicked, you can access the element that was clicked with event.currentTarget
alert( "Search for " + $("#search_input").val() );
}
});
var search_view = new SearchView({ el: $("#search_container") });
</
script
>
-
3.4 提示和技巧
3.4.1 使用模板变量
<
div
id
=
"search_container"
></
div
>
<
script
type
=
"text/template"
id
=
"search_template"
>
<!-- Access template variables with <%= %> -->
<
label
><%= search_label %></
label
>
<
input
type
=
"text"
id
=
"search_input"
/>
<
input
type
=
"button"
id
=
"search_button"
value
=
"Search"
/>
</
script
>
<
script
type
=
"text/javascript"
>
SearchView = Backbone.View.extend({
initialize: function(){
this.render();
},
render: function(){
//Pass variables in using Underscore.js Template
var variables = { search_label: "My Search" };
// Compile the template using underscore
var template = _.template( $("#search_template").html(), variables );
// Load the compiled HTML into the Backbone "el"
this.el.html( template );
},
events: {
"click input[type=button]": "doSearch"
},
doSearch: function( event ){
// Button clicked, you can access the element that was clicked with event.currentTarget
alert( "Search for " + $("#search_input").val() );
}
});
var search_view = new SearchView({ el: $("#search_container") });
</
script
>
-
4. 啥是collection?
Backbone的collections其实就是个有序的models集合。适用于以下情况;
Model: Student, Collection: ClassStudents
Model: Todo Item, Collection: Todo List
Model: Animals, Collection: Zoo
通常你的collection可能只用一个类型的model,但是models并不局限于某一类型的collection;
Model: Student, Collection: Gym Class
Model: Student, Collection: Art Class
Model: Student, Collection: English Class
关于Model/Collection,这里有一个通用的例子。
var
Song = Backbone.Model.extend({
initialize:
function
(){
console.log(
"Music is the answer"
);
}
});
var
Album = Backbone.Collection.extend({
model: Song
});
-
4.1 构建 collection
现在我们来点实在的,下面的例子演示了collection的使用方法。
var
Song = Backbone.Model.extend({
defaults: {
name:
"Not specified"
,
artist:
"Not specified"
},
initialize:
function
(){
console.log(
"Music is the answer"
);
}
});
var
Album = Backbone.Collection.extend({
model: Song
});
var
song1 =
new
Song({ name:
"How Bizarre"
, artist:
"OMC"
});
var
song2 =
new
Song({ name:
"Sexual Healing"
, artist:
"Marvin Gaye"
});
var
song3 =
new
Song({ name:
"Talk It Over In Bed"
, artist:
"OMC"
});
var
myAlbum =
new
Album([ song1, song2, song3]);
console.log( myAlbum.models );
// [song1, song2, song3]
-
5. 啥是router?
//@注1:本章的所有实例都是在http://example.com顶级域名下实现的。
//如果是http://example.com/tset/test.html的形式,则路径标记#前不能加/。
//如:http://example.com/#/user/helphttp://example.com/test/test.html#/user/help
//@注2:Backbone.js 0.9.2 的取路径后的值是posts/12,匹配^/posts/([^/]+)$不能(/posts/:id转换后的正则表达式)。所以原参数要改为posts/:id,测试才能通过。
//以下有错误的地方标红不改,以此类推。
-
Backbone的routers其实就相当于你的应用URL的hash(#)。
如果你读过“啥是view?”,那你应该知道,他们并不符合传统的MVC语义,本章将会详细解释这一点。
尽管Backbone的“router”对任何程序和功能都很有用,但它需要URL的routing/history功能。
Routers的定义包括路径和映射函数,下面的例子就让我们定义一个路径。
还请注意,routes只解析url的“#”之后的标记。
你的应用的所有链接都应该是像“#/action”或“#action”这样。
(附加个斜杠看起来会更好一些,比如:http://example.com/#/user/help)
<script>
var
AppRouter = Backbone.Router.extend({
routes: {
"*actions"
:
"defaultRoute"
// matcheshttp://example.com/#anything-here
},
defaultRoute:
function
( actions ){
// The variable passed in matches the variable in the route definition "actions"
alert( actions );
}
});
// Initiate the router
var
app_router =
new
AppRouter;
// Start Backbone history a neccesary step for bookmarkable URL's
Backbone.history.start();
</script>
_URL进行变化_
[Activate route](
#action)
[Activate another route](
#/route/action)
-
请注意:Backbone 0.5 (released 1. July 2011)之前的版本,Router被称作Controller。为了避免字义混淆,Backbone的开发人员把名字改成Router了。
因此,如果你发现自己使用了Backbone的一个旧版本,那你应该写Backbone.Controller.extend({ ** });
5.1 动态Routing
原始框架允许你的routes定义包含动静混合态路径参数。
例如,你可能想进行检索一个post的id,你的URL看起来可能会是“http://example.com/#/posts/12”。
一旦这个路径被激活,你就可以取到id的值并做相应的处理了。下面是这个例子的实现。
<script>
var
AppRouter = Backbone.Router.extend({
routes: {
"/posts/:id"
:
"getPost"
,
//@注2
"*actions"
:
"defaultRoute"
// Backbone will try match the route above first
},
getPost:
function
( id ) {
// Note the variable in the route definition being passed in here
alert(
"Get post number "
+ id );
},
defaultRoute:
function
( actions ){
alert( actions );
}
});
// Instantiate the router
var
app_router =
new
AppRouter;
// Start Backbone history a neccesary step for bookmarkable URL's
Backbone.history.start();
</script>
_URL进行改变_
[Post 120](
#/posts/120)
[Post 130](
#/posts/130)
-
5.2 动态路径对比——":params"和"*splats"
Backbone使用两种参数模式实现路径,第一种是":params"匹配URL路径内任何斜杠之间的字符串,而还有一种是"splats"匹配任意数量的URL路径。
注意"splat"的本质意思,他总是最后一个变量,因为它匹配的是URL路径之后的全部内容。
在route中定义的任何"*splats"或":params"都会以参数的形式穿入关联函数中。
比如一个route定义了"/:route/:action",那就会传入两个参数(“route”和“action”) 到回调函数中。
下面的示例使用":params"和"*splats"。
routes: {
"/posts/:id"
:
"getPost"
,
//@注2,下同
// <a href="http://example.com/#/posts/121">Example</a>
"/download/*path"
:
"downloadFile"
,
// <a href="http://example.com/#/download/user/images/hey.gif">Download</a>
"/:route/:action"
:
"loadView"
,
// <a href="http://example.com/#/dashboard/graph">LoadRoute/Action View</a>
},
getPost:
function
( id ){
alert(id);
// 121
},
downloadFile:
function
( path ){
alert(path);
// user/images/hey.gif
},
loadView:
function
( route, action ){
alert(route +
"_"
+ action);
// dashboard_graph
}
-
- Backbone.js教程(初级篇) 这是菜鸟与老油条,屌丝与高富帅的战争 —— 译者:茶几 @chajn 原作者:脱袜子·戴蕾丝 原文:http://backbonetutorials.com/
- JS快车下载99%的杯具与茶几
- Apache Storm 官方文档 —— Trident 教程 原文链接 译者:魏勇 Trident 是 Storm 的一种高度抽象的实时计算模型,它可以将高吞吐量(每秒百万级)数据输入、有状
- 我的商业思想的十大变化(原作者: Rob May 原文 译者: ewine)
- WMI 的攻击,防御与取证分析技术之攻击篇 原文出自【比特网】,转载请保留原文链接:http://sec.chinabyte.com/353/13607853.shtml
- 浅谈与DNS(域名系统)相关的攻击 原文出自【比特网】,转载请保留原文链接:http://sec.chinabyte.com/375/12830375.shtml
- 接口与抽象类的区别 原文地址:http://blog.vsharing.com/jekkon/A1604115.html
- cookie与session(上) 转载 原文链接http://blog.sina.com.cn/s/blog_4745d1c10100ihnq.html
- cookie与session(下) 转载 原文链接http://blog.sina.com.cn/s/blog_4745d1c10100ihnq.html
- 进程与线程——原作者写的真好
- 这是转载的 java反射机制与原理,原作者讲解的相对很通俗易懂
- Lua (2)——环境安装(菜鸟教程http://www.runoob.com/)
- linux的硬链接与软连接(转载,原文地址为http://www.cnblogs.com/sonic4x/archive/2011/08/05/2128543.html)
- COM与.NET的互操作(初级)
- cookie与session(再比较) 转载 原文链接http://blog.sina.com.cn/s/blog_4745d1c10100ihnq.html
- JavaScript 计算当天是本年本月的第几周(原文:http://yxgyh.javaeye.com/blog/351630)
- 与微软的战争
- 《开始学Backbone.js》之第三章Backbone Models与Collections(一)
- JAVA 字符串与二进制,十六进制 相互转换
- OCX 控件 内部发消息,网页加载出问题
- 这是我的第一篇文章喔
- Linux下防火墙开启相关端口及查看已开启端口
- linux下jdk+eclipse+python安装
- Backbone.js教程(初级篇) 这是菜鸟与老油条,屌丝与高富帅的战争 —— 译者:茶几 @chajn 原作者:脱袜子·戴蕾丝 原文:http://backbonetutorials.com/
- 第二届云计算展将举行
- 喜欢狗的童鞋可以看看
- 由变量对齐引发的问题
- java socket编程
- linux文件属性详解
- 感动。。。
- 验证通过的db2客户端连接服务端
- 不使用UIImagePickerControllerOriginalImage获取相册图片