【转】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 中设计模式的采用--结构型模式
结构型模式中的适配器模式.外观模式.装饰模式.代理模式都属于包装模式,都是对另外的类或对象的包装,只是各自的意图不同. 适配器模式通过对另外的类或对象的包装,将其接口转换为用户期望 ...
随机推荐
- 使用my exclipse对数据库进行操作(4)
四.删除 public class class4 { public static void main(String[] args) { // TODO Auto-generated method st ...
- 大数据通过PHP快速插入MYSQL的方法
如果您的mysql是通过brew安装的,那么请 vi /usr/local/Cellar/mysql/5.6.23/my.cnf 将 max_allowed_packet = 64M 写入保存并重启m ...
- 最小生成树算法——prim算法
prim算法:从某一点开始,去遍历相邻的边,然后将权值最短的边加入集合,同时将新加入边集中的新点遍历相邻的边更新边值集合(边值集合用来找出新的最小权值边),注意每次更新都需将cost数组中的点对应的权 ...
- 轮播神器swiper插件
Swiper中文网:http://www.swiper.com.cn/ Swiper- 是免费的,最现代化的移动触摸滑块硬件加速的转换和惊人的天然行为.它的目的是在移动网站,移动网络应用和移动本地/混 ...
- js读写Cookie问题(Cookie存储时长、Cookie存储域)汇总
在采集网站用户行为数据/使用js对用户行为做交互时,经常会使用到Cookie,了解Js Cookie的读写,以及一些细节,非常重要. 什么是Cookie 所谓Cookie,只是一条极为短小的信息, ...
- centos安装lamp环境
通过yum安装,需要联网且为su账号 yum -y install httpd php mysql mysql-server php-mysql 设置开启启动mysql,httpd /sbin ...
- Django提交POST表单“CSRF verification failed. Request aborted”问题的解决
1.环境 python 3.4 Django 1.7 Visual Studio 2015 PTVS 2.问题 提交表单,出现以下错误: CSRF verification failed. Reque ...
- Win7 64位 VS2015环境使用qt-msvc2015-5.6.0
QT下载 http://www.qt.io/download-open-source/#section-2 我用的是 qt-opensource-windows-x86-msvc2015-5.6.0. ...
- POJ 2151 Check the difficulty of problems (概率DP)
题意:ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率 ,求每队至少解出一题且冠军队至少解出N道题的概率. 析:概率DP,dp[i][j][k] 表示第 i 个队伍,前 j 个题,解出 ...
- (转)EntityFramework之领域驱动设计实践
EntityFramework之领域驱动设计实践 - 前言 EntityFramework之领域驱动设计实践 (一):从DataTable到EntityObject EntityFramework之领 ...