参考: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标准例子——通讯录的更多相关文章

  1. Win32 OpenGL标准例子

    在VS2008的MSDN中有一个标准的OpenGL例子,记录如下: /* * Example of a Win32 OpenGL program. * The OpenGL code is the s ...

  2. C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 树形选择项目的标准例子

    用成套的现成的方法引导大家开发程序,整个团队的开发效率会很高.例如我们现在有30多个开发人员,若有300个开发人员,这开发工作很容易乱套,我们需要有效的管理维护所有团队的开发工作.把数据结构.通用的组 ...

  3. 隔行换色(WPF DataGrid 标准例子)

     <DataGrid AlternationCount="2">             <DataGrid.RowStyle>               ...

  4. RequireJS与Backbone简单整合

    前言 昨天我们一起学习了Backbone,最后做了一个备忘录的例子,说是做了不如说是看了下官方提供的例子,所以最终我感觉我们还是没能掌握Backbone,今天还得做个其它例子先. 然后前面也只是草草学 ...

  5. Backbone1.0.0数据验证的变化

    0.5.3版本对Model数据验证时,绑定Error就可以了: (function(){ var Model = Backbone.Model.extend({ initialize : functi ...

  6. SAP技术相关Tcode

    ABAP的常用tcode 开发----------------------------------------------- SE51  屏幕制作 SE91  MESSAGE OBJECT SE80  ...

  7. sql 查询基本语法

    1.计算列        select * from emp           --*表示所有的           --from emp 表示从emp表查询   select empno,enam ...

  8. 第四十六课:MVC和MVVM的开发区别

    实现MVC的目的就是为了让M和V相分离.前端的MVC无法做到View和Model的相分离,而MVVM可以. 我们先来看一个用MVC模式开发的经典例子:(一定要深入了解这种开发的思想,而不是看懂代码) ...

  9. ANDROID 中设计模式的采用--结构型模式

            结构型模式中的适配器模式.外观模式.装饰模式.代理模式都属于包装模式,都是对另外的类或对象的包装,只是各自的意图不同. 适配器模式通过对另外的类或对象的包装,将其接口转换为用户期望 ...

随机推荐

  1. 第九章 springboot + mybatis + 多数据源 (AOP实现)(转载)

    本编博客转发自:http://www.cnblogs.com/java-zhao/p/5415896.html 1.ShopDao package com.xxx.firstboot.dao; imp ...

  2. Sql Server 分区之后增加新的分区

    随着时间的推移,你可能会希望为已分区的表添加额外的分区(例如,可以为每一个新年创建一个新的分区).要增加一个新的分区,可以使用ALTER PARTITION SCHEME和ALTER PARTITIO ...

  3. 122. Best Time to Buy and Sell Stock(二) leetcode解题笔记

    122. Best Time to Buy and Sell Stock II Say you have an array for which the ith element is the price ...

  4. jvm 原理和优化

    在csdn 上看到的,觉得很好,收藏了: 原博文地址: 濤子 http://blog.csdn.net/ning109314/article/details/10411495/ JVM工作原理和特点主 ...

  5. 20145202、20145225、20145234 《信息安全系统设计基础》实验五 简单嵌入式WEB 服务器实验

    实验内容 1.配置环境 2.使用vi 编辑器阅读理解源码 2.编译应用程序 运行 make 产生可执行文件httpd 3.下载调试 使用 NFS 服务方式将HTTPD 下载到开发板上,并拷贝测试用的网 ...

  6. 【Java学习笔记】集合转数组---toArray()

    package p2; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class ...

  7. 子进程 已安装 pre-removal 脚本 返回了错误号 1或2 与 子进程 已安装 post-installation 脚本 返回了错误号 1或2

    今天在ubuntu kylin上安装了virtualbox, 后来我想删除了再装个新一点的,结果正常的情况下删除不了,我就把找到的virtualbox的目录全部都删除了, 再通过apt-get rem ...

  8. 学习codeIgniter的一点小感受

    用CI好几天了,最终还是放弃用CI做完整的项目,感觉CI在前后端的交互上还比较差,比如说用户表单验证,仍然是需要把数据提交给服务器之后才能显示逻辑判断的结果.而这一点明显是相对落后了. 但不可否认CI ...

  9. mvc.net 的四种传值方式

    Control: view:

  10. MATLAB 画出三个通信小区cell边界示意图

    d=1000; %两个小区中心间距离的一半 rcell=2*d/sqrt(3); %小区半径 ncell=3; %小区个数 cellposition=zeros(ncell,2); %初始化小区中心位 ...