欢迎大家回来继续这一教程,第一部分我们学习了model,collection和view在Backbone中的

基本用法,还有怎么样用主视图去绑定collection去渲染出每个Contact.

这部分我们学习怎么通过用户输入过滤视图中的数据还要怎么给我们的应用程序加入路由的功能.

响应用户输入

从第一部分你可以发现每个model都有一个属性type,这个属性可以把model分成朋友,家人,同事等等.

让我们给主视图加入一个select控件来对models进行按type类型选择的操作.

我们当然可以将select的option写死,那样显然可维护性很差.虽然我们现在还没有添加或者删除Contacts的

功能,但是肯定将来要添加的.提前透露第三部分教程我们将完成这个功能. 废话还是太多了,肯定是要从现有记录

的type里读取了. 但是之前要先在Contacts的容器里加上装载select的容器.

    <header>
<div id="filter"><label>Show me:</label></div>
</header>

我们用个header元素包裹的指定id的div元素做容器,

下面是在主视图DirectoryView中创建select的代码.

getTypes: function () {
return _.uniq(this.collection.pluck("type"), false, function (type) {
return type.toLowerCase();
});
}, createSelect: function () {
var filter = this.el.find("#filter"),
select = $("<select/>", {
html: "<option>All</option>"
}); _.each(this.getTypes(), function (item) {
var option = $("<option/>", {
value: item.toLowerCase(),
text: item.toLowerCase()
}).appendTo(select);
});
return select;
}

collection.pluck():是Backbone.js的中方法,作用是从Collection中取出所有models的指定属性(这里是type)值得数组.

_.uniq:是Underscore.js中的方法. 去除指定数组中重复的数据. 第一个参数是数组,第二个参数是否重新排序可选true或false.

在这里是去掉pluck后得到数组里的重复元素.第三个参数为function,可以指定对每个数组元素要做的操作.

_.each:是Underscore的方法. 第一个参数是要处理的数组,第二个参数是funtion对每个数组元素的操作.这里把去掉重复数据后

的types数组的每个元分别赋给一个option的value和text属性后添加到select元素里.

最后在初始化结束后initialize()方法里把生成的select的html放入id为filter的div.

this.$el.find("#filter").append(this.createSelect());

$el为Backbone.js视图对象中缓存当前视图的JQuery对象.

过滤视图

现在我们有了select按钮,为了让按钮可以响应过滤models,我们先在主视图中添加一个events属性.

events: {
"change #filter select": "setFilter"
},

这样"change #filter select"(id为filter的tagName为select的子元素值变化)时候执行setFilter方法,我们在补充setFilter方法:

        setFilter: function (e) {
this.filterType = e.currentTarget.value;
this.trigger("change:filterType");
},

在这个方法里先把select的选择结果(e.currentTarget.value)存储到局部变量filterType里,然后触发change:filterType事件.

定义当type改变时候的具体操作方法.

filterByType: function () {
if (this.filterType === "all") {
this.collection.reset(contacts); //重置collection
} else {
this.collection.reset(contacts, { silent: true }); //重置collection但不刷新页面 var filterType = this.filterType,
filtered = _.filter(this.collection.models, function (item) {
return item.get("type").toLowerCase() === filterType;
});
      
this.collection.reset(filtered);
}
}

_.filter是Underscore.js中的方法. 过滤出指定的type的contacts.

对Collection加载监听器

最后挂载事件监听,第一个其实不是针对collection的而是自定义局部变量filterType变量监听.

this.on("change:filterType", this.filterByType, this);

每次对collection执行reset后. view并不会自动刷新前端. 所以还要为reset事件加载监听.

this.collection.on("reset", this.render, this);

这样每当view的collection执行reset. 都会重新render显示的内容.

路由

现在我们可以通过select控件来过滤Contacts,但是如果通过URL来过滤会不会更好呢. Backbone.js的router

就能实现这个功能. 很简单也是使用Backbone.router的extend();

var ContactsRouter = Backbone.Router.extend({
routes: {
"filter/:type": "urlFilter"
}, urlFilter: function (type) {
directory.filterType = type;
directory.trigger("change:filterType");
}
});

用过其他MVC的router对象的一看就明白: routes属性里定义一种路由格式( "filter/:type"). 如果需要也可以扩展更多.

"urlFilter"为路由执行的方法. 下面的urlFilter是方法的实现.

最后在初始化DirectioryView后面初始化一个router.

 var contactsRouter = new ContactsRouter();

然后为了解决浏览器后退问题要再上一句

Backbone.history.start();

为了在type值变化时对应浏览器url的跳转更新filterByType方法. 增加contactsRouter.navigate到指定的url

filterByType: function () {
if (this.filterType === "all") {
this.collection.reset(contacts); <b>contactsRouter.navigate("filter/all");</b> } else {
this.collection.reset(contacts, { silent: true }); var filterType = this.filterType,
filtered = _.filter(this.collection.models, function (item) {
return item.get("type") === filterType;
}); this.collection.reset(filtered); <b>contactsRouter.navigate("filter/" + filterType);</b>
}
}

最后测试一下结果

总结

这部分主要学习了Backbone.js的路由对象.和一些Underscore.js的方法. 例如_.uniq() _.filter()

下一部分教程我们会回到model,学习如何在collection中添加和删除model.

这节课代码:

http://cdn.tutsplus.com/net/uploads/legacy/1143_bb2/demo.zip

用Backbone.js创建一个联系人管理系统(二)的更多相关文章

  1. 用Backbone.js创建一个联系人管理系统(五)

    原文: Build a Contacts Manager Using Backbone.js: Part 5 这是这系列教程最后一部分了. 之前所有的增删改都在前端完成. 这部分我们要把Contact ...

  2. 用Backbone.js创建一个联系人管理系统(一)

    原文 Build a Contacts Manager Using Backbone.js: Part 1 在这个教程里我们将会使用Backbone.js,Underscore.js,JQuery创建 ...

  3. 用Backbone.js创建一个联系人管理系统(四)

    原文: Build a Contacts Manager Using Backbone.js: Part 4 这一系列教程的第四部分,教我们如何完成对已经存在的Contacts进行编辑和保存. 本教程 ...

  4. 用Backbone.js创建一个联系人管理系统(三)

    原文: Build a Contacts Manager Using Backbone.js: Part 3 欢迎回到这系列的教程,关注使用Backbone.js构建应用程序. 如果你还没看过第一,二 ...

  5. 使用 SVG 和 JS 创建一个由星形变心形的动画

    序言:首先,这是一篇学习 SVG 及 JS 动画不可多得的优秀文章.我非常喜欢 Ana Tudor 写的教程.在她的教程中有大量使用 SVG 制作的图解以及实时交互 DEMO,可以说教程的所有细枝末节 ...

  6. 用three.js创建一个简易的天空盒

    本文创建的天空盒是用六张图片来创建的.笔者会论述两种方法来创建,都是最简单基本的方法,不涉及着色器的使用.一种是创建一个盒子,然后将图片作为盒子6个面的纹理贴上来创建.另一种则是简单的将纹理作为场景的 ...

  7. Gitlab创建一个项目(二)创建新用户以及分配项目

    Gitlab创建一个项目(一) 1.进入gitlab控制台 2.点击“新建用户” 3.点击“Edit”,创建初始密码 4.分配项目,首页进入项目 5.进入Members菜单 6.选择用户 7.赋予权限 ...

  8. 十八、Node.js创建Web服务器(二)

    在上一篇文章中我们在自定义模块自定义了几种文件类型的头文件加工的方法: /** * 自定义模块加工响应头文件类型 */ module.exports.getminiName=function (ext ...

  9. JS创建一个数组1.求和 2.求平均值 3.最大值 4.最小值 5.数组逆序 6.数组去重 0.退出

    rs = require("readline-sync"); let arr = []; console.log("请输入数组的长度:"); let arr_l ...

随机推荐

  1. python分布式任务调度Celery

    Celery是Python开发的分布式任务调度模块,今天抽空看了一下,果然接口简单,开发容易,5分钟就写出了一个异步发送邮件的服务. Celery本身不含消息服务,它使用第三方消息服务来传递任务,目前 ...

  2. 4.Single Number && Single Number (II)

    Single Number: 1. Given an array of integers, every element appears twice except for one. Find that ...

  3. LVM原理及实现过程

    这里引用鸟哥说明 LVM 的重点在於『可以弹性的调整 filesystem 的容量!』而并非在於效能与数据保全上面. 需要文件的读写效能或者是数据的可靠性,请参考前面的 RAID 小节. LVM 可以 ...

  4. 重装系统分区时,发现一个叫LVM的东西,找出来和大家分享

    LVM是 Logical Volume Manager(逻辑卷管理)的简写,它是Linux环境下对磁盘分区进行管理的一种机制,它由Heinz Mauelshagen在Linux 2.4内核上实现,目前 ...

  5. 仿淘宝详情转场(iOS,安卓没有这功能)

    由于公司是做跨境电商的,所以对各大电商APP都有关注,最近看到淘宝iOS端(安卓没有)在商品详情点击加入购物车有一个动画效果特别赞,正好今天新版本上线,下午就抽了些时间研究了下. 主要思路是自定义转场 ...

  6. 基于案例贯通 Spark Streaming 流计算框架的运行源码

    本期内容 : Spark Streaming+Spark SQL案例展示 基于案例贯穿Spark Streaming的运行源码 一. 案例代码阐述 : 在线动态计算电商中不同类别中最热门的商品排名,例 ...

  7. css之让文字在一定范围内显示,不超过固定的宽度和高度

  8. 深入理解JS异步编程四(HTML5 Web Worker)

    >Web Workers 是 HTML5 提供的一个javascript多线程解决方案,我们可以将一些大计算量的代码交由web Worker运行而不冻结用户界面. 一:如何使用Worker We ...

  9. Mysql忘记用户密码的解决办法

    1.1 忘记用户密码的解决办法 普通用户,直接用root超级管理员登录进去修改密码就可以了,但是如果root密码丢失了,怎么办呢? 1.1.1 msyqld_saft方式找回密码 停止mysql:se ...

  10. CSS3 display:flex和display:box有什么区别

    父级元素有display:box;属性之后.他的子元素里面加上box-flex属性.可以让子元素按照父元素的宽度进行一定比例的分占空间. 如: html: <article>   < ...