[Backbone] Parse JSON on Collection
// 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 theAppointmentscollection. No problem. We've been here before. Take a look at the JSON the server is responding with below, and then modify theparsefunction to set properties on the collection instance forper_page,total, andpage.
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的更多相关文章
- 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, ...
- JSON.parse() JSON.stringify() eval() jQuery.parseJSON() 的区别
http://www.jb51.net/article/81880.htm : jQuery.parseJSON(jsonString) : 将格式完好的JSON字符串转为与之对应的Java ...
- 使用JSON.parse(),JSON.stringify()实现对对象的深拷贝
根据不包含引用对象的普通数组深拷贝得到启发,不拷贝引用对象,拷贝一个字符串会新辟一个新的存储地址,这样就切断了引用对象的指针联系. 测试例子: var test={ a:"ss", ...
- JSON.parse(JSON.stringify(obj))
JSON.parse(JSON.stringify(obj)实现数组的深拷贝 利用JSON.stringify 将js对象序列化(JSON字符串),再使用JSON.parse来反序列化(还原)js对象
- JSON.parse JSON.stringify
JSON.stringify() undefined 值.函数或者XML值会被忽略 数组当中含有 undefined值,函数或XML值,该数组中的这些值将会被当成 null 正则对象会被转成空对象 J ...
- parse.JSON()报错是什么原因?
哪里出错了? JSON.parse() 会把一个字符串解析成 JSON 对象.如果字符串书写正确,那么其将会被解析成一个有效的 JSON,但是这个字符串被检测出错误语法的时候将会抛出错误. 示例 JS ...
- 【Immutable】拷贝与JSON.parse(JSON.stringify()),深度比较相等与underscore.isEqual(),性能比较
样本:1MB的JSON文件,引入后生成500份的一个数组: 结果如下: 拷贝性能: JSON.parse(JSON.stringify()) 的方法:2523.55517578125ms immuta ...
- JSON.parse(JSON.stringify()) 实现对对象的深拷贝
JSON.parse(JSON.stringify(obj))我们一般用来深拷贝,其过程说白了 就是利用JSON.stringify 将js对象序列化(JSON字符串),再使用JSON.parse来反 ...
- this.treeData = JSON.parse(JSON.stringify(this.d)) 树的序列化反序列化
this.treeData = JSON.parse(JSON.stringify(this.d))
随机推荐
- 顺序线性表之大整数求和C++实现
顺序线性表之大整数求和 大整数求和伪代码 1.初始化进位标志 flag=0: 2.求大整数 A 和 B 的长度: int aLength = a.GetLength(); int bLength = ...
- URAL 1880 Psych Up's Eigenvalues
1880. Psych Up's Eigenvalues Time limit: 0.5 secondMemory limit: 64 MB At one of the contests at the ...
- javaresource 红色X
出现这个问题的原因很多,解决办法也很多,我这里只记录我所遇到的. 这个问题一直存在,但是不影响项目运行. 后来在网上找了下资料,有一篇文章是让修改maven的settings.xml.将jdk1.6修 ...
- LAMP架构之NFS
需求分析: 前端需支持更大的访问量,单台Web服务器已无法满足需求了,则需扩容Web服务器: 虽然动态内容可交由后端的PHP服务器执行,但静态页面还需要Web服务器自己解析,那是否意味着多台Web服务 ...
- Tomcat启动异常 java.net.BindException: Cannot assign requested address: JVM_Bind
从Apache官网下载的tomcat7,在MyEclipse中启动时抛出如下异常: 严重: StandardServer.await: create[localhost:8005]: java.net ...
- GCC 4.9.0 公布,提升 C++11 和 C++14 特性
from :http://www.oschina.net/news/51084/gcc-4-9-0 GCC 4.9.0 公布,此版本号是个主要版本号更新,包含了 GCC 4.8.x 系列和之前的 GC ...
- Java String和Date的转换 Date类型操作
String—>Date String dateString = "2012-12-06 "; try { SimpleDateFormat sdf = new Simple ...
- <jsp:directive.page import=""/>的用法和解释
<jsp:directive.page import="zero.space.ch03.BookBean"/> 相当于 <%@ page import ...
- cocos2d-x 安卓环境配置 -转
win7+cocos2d-x-2.1.4+vs2012环境太简单就不多说了,下面是eclipse环境 一.准备 1.eclipse+adt+sdk:adt-bundle-windows-x86_64- ...
- [翻译] MZTimerLabel 用作秒表或者倒计时
MZTimerLabel 用作秒表或者倒计时 https://github.com/mineschan/MZTimerLabel A handy class for iOS to use UILabe ...