backbone.js初体验--构建简单分页应用时踩到的坑
2015-04-24 15:32
405 查看
最近突然想接触下之前没有接触过的领域,单页应用,正巧之前也是刚刚学习了requirejs的用法,所以趁热打铁选择了很多网站采用的requirejs+underscorejs+backbonejs+jquery(zepto)的方式来进行demo的编写。
这篇文章主要不是介绍怎么去构建一个分页效果的,也不会去讲述backbone的基础知识,而是分享在我构建分页效果时候踩到的一些坑。
1. collection不是必须的
首先,我在开始写的时候就陷入了一个问题,事实证明我真的是多虑了,就是不该用collection的时候,就别去用它了,这个是我在分析堆糖网站源码的时候发现的,整个堆糖就没用到一个collection。
下面来说说为什么:
collection是model的有序集合,model是什么,model就是模型,其实我们做分页的时候,就是不断的问后台要数据,不论是更改页码还是进行排序,其实都是后台再进行操作的,我们做的只是更改路由,去问后台要相应的数据,再填充进html中,所以如果不是对model本身进行增删改查的话,collection就会显得有些冗余了。
2. 慎用collection中的all事件
这个问题其实是跟上面那个问题绑定在一起的,是我强行想要使用collection时遇到的一个问题(洁癖,凑齐MVC三个字母嘛),当时是看到其他的文章,别人的demo中用的就是all事件,于是自己也没动脑筋,不管适合不适合,就先照搬了过来,其实还是有性能上的隐患的,collection是一个model的合集,当一个view不停的在监听collection变化的时候,作为all事件,有一些细小的变换都会导致该事件的触发。
先介绍下前提,再看上面的代码,这里的models里面有24个节点,可以看成是有24个商品的数据,我们的目的是把24个节点的数据渲染到html中。
这里的1被输出了20多次,就是说render被执行了至少24次,因为对于collection来说每一次的变换都会触发回调函数,那我们有24个节点添加入了collection,那自然就有24次的变换,这样代码运行的效率就是非常低的了,当然这里还会有其他的变换,所以数字是大于24的,如果把all改成add,就能准确的看到是24次了,那么我们怎么来解决这个问题呢,我使用的是sort事件,sort事件是当该collection已被重新排序时触发的,这样当分页重新获取数据填充collection时,其实backbone就认为collection是进行了重新排序,而且这个事件只会被触发一次,所以sort事件既能完成任务,又能避免性能的浪费,给他点个赞!
3. view中的el属性
其实我要吐槽的不是el属性,而是events属性,大家都知道bb中定义dom事件是在view中进行的。
就像上面这样定义,但是如果.prev-page不是el属性的子节点的话,就歇菜了!
js部分代码(接口改成假的了,感受下就行):
路由倒是挺好用的,点个赞!今天就写到这里了,以后再有坑就另外开一篇文章了。
这篇文章主要不是介绍怎么去构建一个分页效果的,也不会去讲述backbone的基础知识,而是分享在我构建分页效果时候踩到的一些坑。
1. collection不是必须的
首先,我在开始写的时候就陷入了一个问题,事实证明我真的是多虑了,就是不该用collection的时候,就别去用它了,这个是我在分析堆糖网站源码的时候发现的,整个堆糖就没用到一个collection。
下面来说说为什么:
collection是model的有序集合,model是什么,model就是模型,其实我们做分页的时候,就是不断的问后台要数据,不论是更改页码还是进行排序,其实都是后台再进行操作的,我们做的只是更改路由,去问后台要相应的数据,再填充进html中,所以如果不是对model本身进行增删改查的话,collection就会显得有些冗余了。
2. 慎用collection中的all事件
这个问题其实是跟上面那个问题绑定在一起的,是我强行想要使用collection时遇到的一个问题(洁癖,凑齐MVC三个字母嘛),当时是看到其他的文章,别人的demo中用的就是all事件,于是自己也没动脑筋,不管适合不适合,就先照搬了过来,其实还是有性能上的隐患的,collection是一个model的合集,当一个view不停的在监听collection变化的时候,作为all事件,有一些细小的变换都会导致该事件的触发。
initialize: function() { var _this = this this.page_view = new pageView() this.list = new cnCollection() this.pages = 1 //默认第一页 this.listenTo(this.list, 'all', this.render) //如果使用all,可能会多次触发render }, render: function() { console.log(1) this.models = this.list.models this.pageModels = this.list.page var len = this.models.length, html = '' for (var i = 0; i < len; i++) { html += '<li>' + this.template(this.models[i].toJSON()) + '</li>' } $('#prdList').html(html) this.page_view.render(this.pageModels) }
先介绍下前提,再看上面的代码,这里的models里面有24个节点,可以看成是有24个商品的数据,我们的目的是把24个节点的数据渲染到html中。
这里的1被输出了20多次,就是说render被执行了至少24次,因为对于collection来说每一次的变换都会触发回调函数,那我们有24个节点添加入了collection,那自然就有24次的变换,这样代码运行的效率就是非常低的了,当然这里还会有其他的变换,所以数字是大于24的,如果把all改成add,就能准确的看到是24次了,那么我们怎么来解决这个问题呢,我使用的是sort事件,sort事件是当该collection已被重新排序时触发的,这样当分页重新获取数据填充collection时,其实backbone就认为collection是进行了重新排序,而且这个事件只会被触发一次,所以sort事件既能完成任务,又能避免性能的浪费,给他点个赞!
3. view中的el属性
其实我要吐槽的不是el属性,而是events属性,大家都知道bb中定义dom事件是在view中进行的。
events: { 'click .prev-page': 'goToPrev', 'click .next-page': 'goToNext' }
就像上面这样定义,但是如果.prev-page不是el属性的子节点的话,就歇菜了!
js部分代码(接口改成假的了,感受下就行):
var cnModel = B.Model.extend({});
/* 列表Collection */
var cnCollection = B.Collection.extend({
model: cnModel,
parse: function(res) {
this.page = res.data.page
return (res && res.data && res.data.list) || {}
}
});
/* 列表View */
var cnView = B.View.extend({
el: $('.g-warp'),
events: { 'click .prev-page': 'goToPrev', 'click .next-page': 'goToNext' },
template: _.template($('#list-template').html()),
initialize: function() {
var _this = this
this.page_view = new pageView()
this.list = new cnCollection()
this.pages = 1 //默认第一页
this.listenTo(this.list, 'sort', this.render) //如果使用all,可能会多次触发render
},
render: function() {
this.models = this.list.models
this.pageModels = this.list.page
var len = this.models.length,
html = ''
for (var i = 0; i < len; i++) {
html += '<li>' + this.template(this.models[i].toJSON()) + '</li>'
}
$('#prdList').html(html)
this.page_view.render(this.pageModels)
},
goToPrev: function() {
this.changeRoutes(-1)
},
goToNext: function() {
this.changeRoutes(1)
},
changeRoutes: function(args) {
var pageCount = this.list.page.page_count
this.pages = this.pages + args
if (this.pages <= 0) {
this.pages = 1
alert("已经是第一页")
return false
} else if (this.pages > pageCount) {
this.pages = pageCount
alert("一共就" + pageCount + "页")
return false
}
mr.navigate("/pages" + this.pages, {
trigger: true
});
}
});
/* 页码View */
var pageView = B.View.extend({
template: _.template($('#page-template').html()),
render: function(args) {
$('#pageCount').html(this.template(args))
}
});
var myRouter = B.Router.extend({
initialize: function() {
this.view = new cnView()
},
routes: {
'': 'index',
'pages:num': 'pages'
},
index: function() {
this.view.list.url = 'http://xxx.com/a.php?mod=Search&act=page&option=&p=' + 1 + '&callback=?'
this.view.list.fetch({
success: function() {
$(".loading-content").hide()
}
})
},
pages: function(num) {
$(".loading-content").show()
this.view.list.url = 'http:/xxx.com/a.php?mod=Search&act=page&option=&p=' + num + '&callback=?'
this.view.pages = Number(num)
this.view.list.fetch({
success: function() {
$(".loading-content").hide()
}
})
}
});
var mr = new myRouter();
B.history.start();
路由倒是挺好用的,点个赞!今天就写到这里了,以后再有坑就另外开一篇文章了。
相关文章推荐
- Asp.net+Vue2构建简单记账WebApp之三(使用Vue-cli构建vue.js应用)
- Asp.net+Vue2构建简单记账WebApp之三(使用Vue-cli构建vue.js应用)
- 使用require.js和backbone实现简单单页应用实践
- 【最简单】Electron 怎么将网页打包成桌面应用(web前端页面怎么生成exe可执行文件) 标签: 跨平台node.js桌面应用electronelectron-packager 2017-04-
- nodejs简单爬虫->获取分页数据->下载多特的应用信息
- 基于MINA构建简单高性能的NIO应用
- 发邮件 上传图像 JS中的EVENT GRIDVIEW的简单应用 JS中一些寻找控件的用法
- 用Backbone.js来构建可扩展的应用程序 (Boilerplate)
- 关于GridView中自定义分页、单选、多选、排序、自增列的简单应用(原创)
- 开发Backbone.js应用[0]--写在前面
- 快速构建Windows 8风格应用21-构建简单媒体播放器
- 基于nodejs 的微信 JS-SDK 简单应用
- stenciljs 学习二 pwa 简单应用开发
- 使用Beetle.Express简单构建高吞吐的TCP&UDP应用
- 为一个 iOS 应用编写一个简单的 Node.js/MongoDB Web 服务
- Maven学习笔记(一) 安装和构建简单应用
- js中bind、call、apply区别和简单应用
- 基于Vue2.0+Vue-router构建一个简单的单页应用
- 用 React.js 写一个最简单的 To-do List 应用
- Vue.js教程: 构建一个预渲染SEO友好的应用示例