【转】Backbone标准例子——通讯录
参考:http://z2009zxiaolong.iteye.com/blog/1847833
感觉不错的例子,模型、视图、路由等知识点都用到了:),将此文中的源码转载如下:
http://dmyz.org/archives/598 这篇教程也不错,讲的很清楚。
//------------------------------------------------------------------------------------
backbone.js源码初略:
backbone.js相当轻量级,以其0.5.1 版本为例,总代码不过1100行左右。主要代码包括:
event:定义一个event和callback的list,实现时间的增、删即回调;
async:封装http的post\delete\get\update方法;
model:定义数据模型对象,主要是其属性(比如url)以及关键的回调,比如fetch会调用async模块的ajax方法获取数据,并执行回调;
collection:是model的集合,在这个集合中实现了一堆方法的扩展接口,例如foreach,each,map等等;
route:定义一个route列表,操作时会相应操作history对象,实现历史跳转;
view:对应视图,主要是获取其中的DOM组件并渲染,同时处理绑定在view上的事件;
//-------------------------------------------------------------------------------------
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Backbone通讯录</title>
<link rel="stylesheet" href="css/application.css" type="text/css" charset="utf-8">
</head>
<body>
<header id="header"><h1>Backbone通讯录</h1></header>
<article id="article"></article>
</body>
<script src="js/lib/jquery.js" type="text/javascript" charset="utf-8"></script>
<script src="js/lib/underscore.js" type="text/javascript" charset="utf-8"></script>
<script src="js/lib/backbone.js" type="text/javascript" charset="utf-8"></script>
<script src="js/lib/backbone-localstorage.js" type="text/javascript" charset="utf-8"></script>
<script src="js/application.js" type="text/javascript" charset="utf-8"></script> <!-- 联系人 -->
<script type="text/template" id="tpl-item">
<%= (name ? name : "<i>无名</i>") %>
</script> <!-- 左边的侧边条,包括联系人列表 -->
<script type="text/template" id="tpl-sidebar">
<header>
<input type="search" placeholder="搜索" results="0" incremental="true" autofocus>
</header>
<div class="items"></div>
<footer>
<button>新建联系人</button>
</footer>
</script> <!-- 显示联系人详细信息 -->
<script type="text/template" id="tpl-show">
<header>
<a class="edit">编辑</a>
</header>
<div class="content">
<p><label>姓名:<%= name %></label></p>
<p><label>邮箱:<%= email %></label></p>
</div>
</script> <!-- 编辑联系人信息 -->
<script type="text/template" id="tpl-edit">
<header>
<a class="save">保存</a>
<a class="delete">删除</a>
</header>
<div class="content">
<form>
<label>
<span>姓名:</span>
<input type="text" name="name" value="<%= name %>">
</label>
<label>
<span>邮箱:</span>
<input type="email" name="email" value="<%= email %>">
</label>
<button>保存</button>
</form>
</div>
</script>
</html>
(function($) {
$(document).ready(function() {
var Contact = Backbone.Model.extend({
defaults: {
name: '',
email: ''
},
validate: function(attrs, options) {
if (attrs.name == "") {
return "用户名不能为空!";
};
},
// 用户搜索的辅助方法
filter: function(query) {
if (typeof(query) === 'undefined' || query === null || query === '') return true;
query = query.toLowerCase();
return this.get('name').toLowerCase().indexOf(query) != -1 || this.get('email').toLowerCase().indexOf(query) != -1;
}
});
var Contacts = Backbone.Collection.extend({
model: Contact,
localStorage: new Store('my-contacts')
});
// 单个联系人视图
var ContactItemView = Backbone.View.extend({
className: 'item',
template: _.template($('#tpl-item').html()),
events: {
'click': 'select'
},
initialize: function() {
_.bindAll(this, 'select');
this.model.bind('reset', this.render, this);
this.model.bind('change', this.render, this);
this.model.bind('destroy', this.remove, this);
if (this.model.view) this.model.view.remove();
this.model.view = this;
},
// 渲染联系人
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
select: function() {
appRouter.navigate('contacts/' + this.model.cid, {
trigger: true
});
},
active: function() {
this.$el.addClass('active');
},
deactive: function() {
this.$el.removeClass('active');
}
});
// 左边的侧边条视图
var SidebarView = Backbone.View.extend({
className: 'sidebar',
template: _.template($('#tpl-sidebar').html()),
events: {
'click footer button': 'create',
'click input': 'filter',
'keyup input': 'filter'
},
initialize: function() {
_.bindAll(this, 'create', 'filter');
this.model.bind('reset', this.renderAll, this);
this.model.bind('add', this.add, this);
this.model.bind('remove', this.remove, this);
},
// 渲染联系人列表
render: function() {
$(this.el).html(this.template());
this.renderAll();
return this;
},
renderAll: function() {
this.$(".items").empty();
this.model.each(this.renderOne, this);
this.filter();
},
renderOne: function(contact) {
var view = new ContactItemView({
model: contact
});
this.$(".items").append(view.render().el);
},
create: function() {
var contact = new Contact();
this.model.add(contact);
appRouter.navigate('contacts/' + contact.cid + '/edit', {
trigger: true
});
},
filter: function() {
var query = $('input', this.el).val();
this.model.each(function(contact, element, index, list) {
contact.view.$el.toggle(contact.filter(query));
});
// this.model.last().view.$el.trigger("click")
},
active: function(item) {
if (this.activeItem) this.activeItem.view.deactive();
this.activeItem = item;
if (this.activeItem) this.activeItem.view.active();
},
add: function(contact) {
this.renderOne(contact);
},
remove: function(contact) {
console.log(contact);
}
});
// 显示选择的联系人详细信息
var ShowView = Backbone.View.extend({
className: 'show',
template: _.template($('#tpl-show').html()),
events: {
'click .edit': 'edit'
},
initialize: function() {
_.bindAll(this, 'edit');
},
render: function() {
if (this.item) this.$el.html(this.template(this.item.toJSON()));
return this;
},
change: function(item) {
this.item = item;
this.render();
},
edit: function() {
if (this.item) appRouter.navigate('contacts/' + this.item.cid + '/edit', {
trigger: true
});
}
});
// 编辑选择的联系人
var EditView = Backbone.View.extend({
className: 'edit',
template: _.template($('#tpl-edit').html()),
events: {
'submit form': 'submit',
'click .save': 'submit',
'click .delete': 'remove'
},
initialize: function() {
_.bindAll(this, 'submit', 'remove');
},
render: function() {
if (this.item) this.$el.html(this.template(this.item.toJSON()));
return this;
},
change: function(item) {
this.item = item;
this.render();
},
submit: function() {
this.item.set(this.form());
this.item.save();
appRouter.navigate('contacts/' + this.item.cid, {
trigger: true
});
return false;
},
form: function() {
return {
name: this.$('form [name="name"]').val(),
email: this.$('form [name="email"]').val()
};
},
remove: function() {
this.item.destroy();
this.item = null;
appRouter.navigate('', {
trigger: true
});
}
});
// 主视图,显示和编辑联系人
var MainView = Backbone.View.extend({
className: 'main stack',
initialize: function() {
this.editView = new EditView();
this.showView = new ShowView();
},
render: function() {
this.$el.append(this.showView.render().el);
this.$el.append(this.editView.render().el);
return this;
},
edit: function(item) {
this.showView.$el.removeClass('active');
this.editView.$el.addClass('active');
this.editView.change(item);
},
show: function(item) {
this.editView.$el.removeClass('active');
this.showView.$el.addClass('active');
this.showView.change(item);
}
});
// 整个页面的视图,管理SiderbarView和MainView两个子视图
var AppView = Backbone.View.extend({
className: 'contacts',
initialize: function() {
this.sidebar = new SidebarView({
model: this.model
});
this.main = new MainView();
this.vdiv = $('<div />').addClass('vdivide');
this.model.fetch();
this.render();
},
render: function() {
this.$el.append(this.sidebar.render().el);
this.$el.append(this.vdiv);
this.$el.append(this.main.render().el);
$('#article').append(this.el);
return this;
},
show: function(item) {
this.sidebar.active(item);
this.main.show(item);
},
edit: function(item) {
this.sidebar.active(item);
this.main.edit(item);
}
});
// 路由
var AppRouter = Backbone.Router.extend({
routes: {
'': 'show',
'contacts/:id': 'show',
'contacts/:id/edit': 'edit'
},
show: function(id) {
if (id != undefined) {
appView.show(this.getContact(id));
} else {
appView.show(contacts.first());
}
},
edit: function(id) {
appView.edit(this.getContact(id));
},
getContact: function(id) {
return contacts.getByCid(id);
}
});
var contacts = new Contacts();
window.appView = new AppView({
model: contacts
});
window.appRouter = new AppRouter();
Backbone.history.start();
});
})(jQuery);
【转】Backbone标准例子——通讯录的更多相关文章
- Win32 OpenGL标准例子
在VS2008的MSDN中有一个标准的OpenGL例子,记录如下: /* * Example of a Win32 OpenGL program. * The OpenGL code is the s ...
- C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 树形选择项目的标准例子
用成套的现成的方法引导大家开发程序,整个团队的开发效率会很高.例如我们现在有30多个开发人员,若有300个开发人员,这开发工作很容易乱套,我们需要有效的管理维护所有团队的开发工作.把数据结构.通用的组 ...
- 隔行换色(WPF DataGrid 标准例子)
<DataGrid AlternationCount="2"> <DataGrid.RowStyle> ...
- RequireJS与Backbone简单整合
前言 昨天我们一起学习了Backbone,最后做了一个备忘录的例子,说是做了不如说是看了下官方提供的例子,所以最终我感觉我们还是没能掌握Backbone,今天还得做个其它例子先. 然后前面也只是草草学 ...
- Backbone1.0.0数据验证的变化
0.5.3版本对Model数据验证时,绑定Error就可以了: (function(){ var Model = Backbone.Model.extend({ initialize : functi ...
- SAP技术相关Tcode
ABAP的常用tcode 开发----------------------------------------------- SE51 屏幕制作 SE91 MESSAGE OBJECT SE80 ...
- sql 查询基本语法
1.计算列 select * from emp --*表示所有的 --from emp 表示从emp表查询 select empno,enam ...
- 第四十六课:MVC和MVVM的开发区别
实现MVC的目的就是为了让M和V相分离.前端的MVC无法做到View和Model的相分离,而MVVM可以. 我们先来看一个用MVC模式开发的经典例子:(一定要深入了解这种开发的思想,而不是看懂代码) ...
- ANDROID 中设计模式的采用--结构型模式
结构型模式中的适配器模式.外观模式.装饰模式.代理模式都属于包装模式,都是对另外的类或对象的包装,只是各自的意图不同. 适配器模式通过对另外的类或对象的包装,将其接口转换为用户期望 ...
随机推荐
- win2008 IIS与php整合
首先安装好IIS 安装的时候 要注意三个地方打得勾 注: CGI 会在IIS+PHP的环境中用到 php.ini default_socket_timeout = 60extension_dir ...
- <停车位>version1.0
<停车卫> 产品需求说明书 文档版本号: Version 1.0 文档编号: xxxx 文档密级: 归属部门/项目: 产品名: 停车卫 子系统名: 编写人: kina 编写日期: 2015 ...
- DSP(2) -- 离散时间信号的序列运算
1.信号相加:这是一种对应的样本与样本之间的相加. 在Matlab中它可用算术运算符“+”实现,然后x1和x2的长度必须相等.如果序列不等,或者长度虽然相等但采样的位置不同,就不能用运算符“+”了.我 ...
- 123. Best Time to Buy and Sell Stock (三) leetcode解题笔记
123. Best Time to Buy and Sell Stock III Say you have an array for which the ith element is the pric ...
- [翻译][erlang]cowboy handler模块的使用
关于Cowboy Cowboy是基于Erlang实现的一个轻量级.快速.模块化的http web服务器. Handlers,用于处理HTTP请求的程序处理模块. Plain HTTP Handlers ...
- SAAS在中国市场的发展前景
发展现状 2008年1-7月软件行业实现收入4199.1亿元,同比增长32.4%.2008年第一季度,业务管理软件市场总量达16.31亿元,同比增长17.8%.面对成本的上升,企业选择了向信息化要效率 ...
- hdoj 2034 人见人爱A-B
Problem Description 参加过上个月月赛的同学一定还记得其中的一个最简单的题目,就是{A}+{B},那个题目求的是两个集合的并集,今天我们这个A-B求的是两个集合的差,就是做集合的减法 ...
- Web调试利器OpenWindow
有些时候调试web页面,在循环里面我们不方便设置断点进行调试,或者调试起来比较麻烦,我们就可以用openWindow的方法打印出想要查看的信息,既方便又省时. 代码如下: OpenWindow = w ...
- Task set generation
Task set generation for uni- and multiprocessors: “Unifying Fixed- and Dynamic-Priority Scheduling b ...
- CentOS 7下设置DNS服务器
在CentOS 7下,手工设置 /etc/resolv.conf 里的DNS,过了一会,发现被系统重新覆盖或者清除了.和CentOS 6下的设置DNS方法不同,有几种方式: 1.使用全新的命令行工具 ...