// Get /appointments
{
"per_page": 10, "page": 1, "total": 50,
"appointments": [
{ "title": "Ms. Kitty Hairball Treatment", "cankelled": false, "identifier": 1 }
]
} The server team is at it again, but this time they at least have a good reason: they want to start paginating appointments instead of just returning all of them when we fetch the Appointmentscollection. No problem. We've been here before. Take a look at the JSON the server is responding with below, and then modify the parse function to set properties on the collection instance for per_pagetotal, and page.
var Appointments = Backbone.Collection.extend({
parse: function(response){
this.per_page = response.per_page;
this.total = response.total;
this.page = response.page;
return response;
}
});

Fantastic work! Now to finish the job, just return the appointments array from the parse function, instead of the entire response.

// Get /appointments
{
"per_page": 10, "page": 1, "total": 50,
"appointments": [
{ "title": "Ms. Kitty Hairball Treatment", "cankelled": false, "identifier": 1 }
]
}
var Appointments = Backbone.Collection.extend({
parse: function(response){
this.perPage = response.per_page;
this.page = response.page;
this.total = response.total;
response = response.appointments
return response;
}
});

The server team has implemented a feature for limiting the appointments pulled down based on the appointment date. In the code below, update the fetch call to pass an extra param so that the URL is like:/appointments?since=2013-01-01

var appointments = new Appointments();
appointments.fetch({data: {since: '2013-01-01'}});

We can limit the number of appointments returned by passing in a per_page parameter also. Go ahead and construct the fetch call below to create a URL that looks like /appointments?since=2013-01-01&per_page=10

var appointments = new Appointments();
appointments.fetch({data: {since: "2013-01-01", per_page: 10}});

Let's start to implement this feature by adding a template to the AppointmentListView below. The template should have a link that looks like this: <a href="#/appointments/p<%= page %>/pp<%= per_page %>">View Next</a>

var AppointmentListView = Backbone.View.extend({
//Using template display the Next page
template: _.template('<a href="#/appointments/p<%= page %>/pp<%= per_page %>">View Next</a>'),
initialize: function(){
this.collection.on('reset', this.render, this);
},
render: function(){
thi.$el.empty();
this.collection.forEach(this.addOne, this);
},
addOne: function(model){
var appointmentView = new AppointmentView({model: model});
appointmentView.render();
this.$el.append(appointmentView.el);
}
});

let's add some code in the render function to append the generated HTML from the template into the AppointmentListView $el. Make sure you pass in thepage and per_page properties to the template function, getting those values fromthis.collection.page + 1 and this.collection.per_page respectively.

var AppointmentListView = Backbone.View.extend({
template: _.template('<a href="#/appointments/p<%= page %>/pp<%= per_page %>">View Next</a>'),
initialize: function(){
this.collection.on('reset', this.render, this);
},
render: function(){
this.$el.empty();
this.collection.forEach(this.addOne, this);
this.$el.append(this.template({page:this.collection.page + 1, per_page:this.collection.per_page}));
},
addOne: function(model){
var appointmentView = new AppointmentView({model: model});
appointmentView.render();
this.$el.append(appointmentView.el);
}
});

Now that we are rendering the link, we need to implement the route to handleappointments/p:page/pp:per_page and have the route function fetch the new appointments based on the parameters. Name this new function page.

var AppRouter = new (Backbone.Router.extend({
routes: {
"": "index",
"appointments/p:page/pp:per_page": "page"
},
initialize: function(options){
this.appointmentList = new AppointmentList();
},
index: function(){
var appointmentsView = new AppointmentListView({collection: this.appointmentList});
appointmentsView.render();
$('#app').html(appointmentsView.el);
this.appointmentList.fetch();
},
page: function(page, per_page){
this.appointmentList.fetch({data:{page: page, per_page: per_page}});
}
}));

Our appointments are being rendered in a pretty haphazard way. Dr. Goodparts is very chronological, so we need to always have our appointments sorted by the date. Add the code below to accomplish this.

var Appointments = Backbone.Collection.extend({
comparator: "date"
});
var app1 = new Appointment({date: "2013-01-01"});
var app2 = new Appointment({date: "2013-02-01"});
var app3 = new Appointment({date: "2013-01-15"});
var app4 = new Appointment({date: "2013-01-09"});
var appointments = new Appointments();
appointments.add(app1);
appointments.add(app2);
appointments.add(app3);
appointments.add(app4);

Dr. Goodparts just sent us this email "Love the new sorting, but please flip it and reverse it", Update the comparator below to sort by date in reverse order

var Appointments = Backbone.Collection.extend({
comparator: function(ap1, ap2){
return ap1.get('date') < ap2.get('date');
}
});

implement a function on the collection to count up the number of cancelled appointments. Implement this function in the collection class below and call it cancelledCount.

var Appointments = Backbone.Collection.extend({
cancelledCount: function(){
return this.where({'cancelled': true}).length;
}
});

----------------------------Final Code------------------------

var Appointments = Backbone.Collection.extend({
// comparator: "date",
comparator: function(ap1, ap2){
return ap1.get('date') < ap2.get('date');
},
cancelledCount: function(){
return this.where({'cancelled': true}).length;
},
parse: function(response){
this.perPage = response.per_page;
this.page = response.page;
this.total = response.total;
response = response.appointments
return response;
}
});
var appointments = new Appointments();
appointments.fetch({data: {since: "2013-01-01", per_page: 10}});
var AppointmentListView = Backbone.View.extend({
template: _.template('<a href="#/appointments/p<%= page %>/pp<%= per_page %>">View Next</a>'),
initialize: function(){
this.collection.on('reset', this.render, this);
},
render: function(){
this.$el.empty();
this.collection.forEach(this.addOne, this);
this.$el.append(this.template({page:this.collection.page + 1, per_page:this.collection.per_page}));
},
addOne: function(model){
var appointmentView = new AppointmentView({model: model});
appointmentView.render();
this.$el.append(appointmentView.el);
}
});
var AppRouter = new (Backbone.Router.extend({
routes: {
"": "index",
"appointments/p:page/pp:per_page": "page"
},
initialize: function(options){
this.appointmentList = new AppointmentList();
},
index: function(){
var appointmentsView = new AppointmentListView({collection: this.appointmentList});
appointmentsView.render();
$('#app').html(appointmentsView.el);
this.appointmentList.fetch();
},
page: function(page, per_page){
this.appointmentList.fetch({data:{page: page, per_page: per_page}});
}
}));

[Backbone] Parse JSON on Collection的更多相关文章

  1. Guzzle Unable to parse JSON data: JSON_ERROR_SYNTAX - Syntax error, malformed JSON

    项目更新到正式平台时,出现Guzzle(5.3) client get请求出现:Unable to parse JSON data: JSON_ERROR_SYNTAX - Syntax error, ...

  2. JSON.parse() JSON.stringify() eval() jQuery.parseJSON() 的区别

    http://www.jb51.net/article/81880.htm    :   jQuery.parseJSON(jsonString) : 将格式完好的JSON字符串转为与之对应的Java ...

  3. 使用JSON.parse(),JSON.stringify()实现对对象的深拷贝

    根据不包含引用对象的普通数组深拷贝得到启发,不拷贝引用对象,拷贝一个字符串会新辟一个新的存储地址,这样就切断了引用对象的指针联系. 测试例子: var test={ a:"ss", ...

  4. JSON.parse(JSON.stringify(obj))

    JSON.parse(JSON.stringify(obj)实现数组的深拷贝 利用JSON.stringify 将js对象序列化(JSON字符串),再使用JSON.parse来反序列化(还原)js对象

  5. JSON.parse JSON.stringify

    JSON.stringify() undefined 值.函数或者XML值会被忽略 数组当中含有 undefined值,函数或XML值,该数组中的这些值将会被当成 null 正则对象会被转成空对象 J ...

  6. parse.JSON()报错是什么原因?

    哪里出错了? JSON.parse() 会把一个字符串解析成 JSON 对象.如果字符串书写正确,那么其将会被解析成一个有效的 JSON,但是这个字符串被检测出错误语法的时候将会抛出错误. 示例 JS ...

  7. 【Immutable】拷贝与JSON.parse(JSON.stringify()),深度比较相等与underscore.isEqual(),性能比较

    样本:1MB的JSON文件,引入后生成500份的一个数组: 结果如下: 拷贝性能: JSON.parse(JSON.stringify()) 的方法:2523.55517578125ms immuta ...

  8. JSON.parse(JSON.stringify()) 实现对对象的深拷贝

    JSON.parse(JSON.stringify(obj))我们一般用来深拷贝,其过程说白了 就是利用JSON.stringify 将js对象序列化(JSON字符串),再使用JSON.parse来反 ...

  9. this.treeData = JSON.parse(JSON.stringify(this.d)) 树的序列化反序列化

    this.treeData = JSON.parse(JSON.stringify(this.d))

随机推荐

  1. AFNetworking源码品读

    AFNetworking源码品读 AFNetworking这个库几乎是所有苹果开发人员在使用HTTP协议的第一选择,为什么这个库会有这么大的吸引力呢?其实答案就需要问问自己,为什么会用它,而不是别的库 ...

  2. TCP的建立和终止 图解

    前言 在没有理解TCP连接是如何建立和终止之前,我想你可能并不会使用connect,accept,close这三个函数并且使用netstat程序来调试应用.所以掌握TCP连接的建立和终止势在必行. 三 ...

  3. 模板 SBT

    傻逼树模板 struct SBT{ const static int maxn = 1e5 + 15; int lft[maxn] , rht[maxn] , key[maxn] , s[maxn] ...

  4. 关于php一些问题

    为什么说php是弱语言? 本身不严格区分变量的类型. 为什么说php是动态语言? 程序在运行时可以改变其结构.所谓的动态类型语言,意思就是类型的检查是在运行时做的. 为什么说php是脚本语言? 不需要 ...

  5. Maven系列--setting.xml 配置详解

    文件存放位置 全局配置: ${M2_HOME}/conf/settings.xml 用户配置: ${user.home}/.m2/settings.xml note:用户配置优先于全局配置.${use ...

  6. C/C++服务器开发的必备利器–libconfig

    http://www.leoox.com/?p=311 程序肯定需要一份配置文件,要不然,自己的程序不是“可配置”的,自己都不好意思往“高大上”靠拢.言归正传,以前自己写代码,配置文件的读写都是各式各 ...

  7. ztree插件的使用及列表项拖拽的实现(jQuery)+异步加载节点数据

    为了实现如图所示的树状结构图,并使列表项可拖动到盒子里,研究了ztree这个插件的使用,并仔细研究了列表项的拖动事件.完成了预期需求,对jQuery的运用得到了提高.这个插件的功能非常强大,除了基本的 ...

  8. maven切换到阿里云镜像

    maven默认去中央仓库下载jar速度奇慢,切换成阿里的镜像源会快很多 maven  settings.xml配置 <?xml version="1.0" encoding= ...

  9. BTA 常问的 Java基础40道常见面试题及详细答案

    原文:http://www.ymq.io/2018/03/10/java/ 八种基本数据类型的大小,以及他们的封装类 引用数据类型 Switch能否用string做参数 equals与==的区别 自动 ...

  10. xml转换成map

    import java.io.IOException;import java.io.StringReader;import java.util.ArrayList;import java.util.H ...