博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【再探backbone 03】博客园单页应用实例(提供源码)
阅读量:6292 次
发布时间:2019-06-22

本文共 7053 字,大约阅读时间需要 23 分钟。

前言

之前尝试性的读了下backbone的源码,对继承、事件、view一块还比较熟悉,看下去比较顺畅,但是在model collection方面就很不顺利

究其原因还是没有使用过,不够熟悉,以码读码,脱离了业务逻辑的代码毫无意义,所以今天我们先来做一个例子吧,然后再根据例子学习

今天来一段官网以外的代码,本来这里想抄一个代码来着,但是这样的话好像意义就不大了,于是自己重新写一个例子吧

注意这个例子只是简单例子,各位不要当真,而且代码是今天下午写的,有BUG不要骂我,然后放到IIS环境下才有数据

下载源码:

单页应用实例

以博客园为例,我们一起做一个单页,提供list和detail两个页面,并且为list提供分页和简单筛选功能来巩固我们的backbone学习

文件结构

首先为了简单起见,我们这里目录暂时如下:

其中css样式是上次做单页应用研究剩下的,这次直接拿来用吧

数据源

然后,我们来简单看看我们博客园的数据源返回的数据:

很遗憾博客园暂时只提供了xml的返回格式,其中我自己做了json的解析,其实就算我自己不做解析,也可以通过model的parse做解析

但是我没有那么蛋疼,这里还是使用后台方法解析吧

Model/Collection

有了数据源,我们就需要对其创建数据模型了,这里可以与他统一反正数据model会自己对应

我们知道Model可以设置URL,自己从服务器获取数据(只不过必须是rest请求),我们这里来试试

1 //博客模型 2 var PostModel = Backbone.Model.extend({ 3  4 }); 5  6 //模型集合 7 var PostList = Backbone.Collection.extend({ 8   model: PostModel 9 });10 var curpage = 1;11 var pageSize = 10;12 var list = new PostList();13 list.url = 'Handler.ashx?url=http://wcf.open.cnblogs.com/blog/sitehome/paged/' + curpage + '/' + pageSize;14 list.fetch();

我们这里事实上只需要获取数据即可,如此变会发起一个请求,数据返回与上述截图一致

有了数据我们就需要根据数据对model进行填充,一次实例化model加入collection

我们这里使用parse对返回数据进行处理,于是他自己就将model填充到model里面去了

parse: function (data) {  // 'data' contains the raw JSON object  return (data && data.feed && data.feed.entry) || {}}list.fetch({  success: function () {    var s = '';  }});

需要注意一点是这里是异步的,所以不要傻傻的马上想在后面操作数据

视图-View

现在数据模型与集合都有了,我们需要一个承载他的页面,于是我们先随便搞下将数据显示出来:

① 定义模板

1 

这是我们之前使用过的数据模板,这里直接搞过来使用了

② 定义view

并在集合数据加载结束调用render方法

1 var View = Backbone.View.extend({ 2   template: _.template($('#item-template').html()), 3   initialize: function () { 4     var scope = this; 5     var curpage = 1; 6     var pageSize = 10; 7     this.list = new PostList(); 8     this.list.url = 'Handler.ashx?url=http://wcf.open.cnblogs.com/blog/sitehome/paged/' + curpage + '/' + pageSize; 9     this.list.fetch({10       success: function () {11         scope.render();12       }13     });14     this.wrapper = $('#lstbox');15   },16   render: function () {17     var models = this.list.models;18     var html = '';19     for (var i = 0, len = models.length; i < len; i++) {20       html += this.template(models[i].toJSON());21 22     }23     this.wrapper.html(html);24     var s = '';25   }26 });

③ 实例化view

var view = new View();

于是我们的view就出来了:

附上完整html代码:

1   2   3   4   
5 6
7
8
9 19 20 21
22
23
24
25

26 博客园

27
28
29
30
    31
32
33
39
40
41 64 65 66 67 68 114 115
完整Html代码

到现在为止,我们只是简单将视图展示了出来,现在我们来多用一点集合与模型的操作,深入之前的学习

操作集合/模型

这里又有个比较遗憾的地方就是,我们并不需要写数据到服务器,我这里也不准备调用写的接口,所以model又被边缘化了......

集合排序

我们这里对下面的几个做一个排序处理,比如按时间排序,按推荐数排序等,这里就要用的集合里面的操作了

然后我们来看看我们如何只改变集合的数据,而让dom自己发生变化

有一点需要注意的是,我们现在还不是完整的单页,后面引入路由时候慢慢改进程序结构

首先我们需要为下面几个可爱的按钮绑定点击事件:

1   
1 events: {2   'click #sort': function (e) {3     var el = $(e.target);4     var sort = el.attr('attr');5 6     var s = '';7   }8 },

events: {  'click #sort': function (e) {    var el = $(e.target);    var type = el.attr('attr');    this.list.setComparator(type);    this.list.sort();  }},//list新增方法setComparator: function (type) {  this.comparator = function (item) {    return Math.max(item.attributes[type]);  }}

这个时候在初始化时候再注册一个事件

this.listenTo(this.list, 'all', this.render);

于是就能点击不同的标签按不同的倒叙排列,这里注意一点是每次改变都会触发list的all事件(其实应该是reset),完了触发view的render重新渲染了下数据

1   2   3   4   
5 6
7
8
9 19 20 21
22
23
24
25 43 66 67 68 69 70 138 139
完整代码

这里对集合的操作暂时到此,对model的操作仍然没有涉及,我们先引入路由再说吧

Control-引入路由

MVC中View的代码量可能很大,但是Control的代码往往才是核心,他全局观察着整个程序的运作,但是这里却给他换了个名字——路由

其实这个名字比较靠谱,Backbone中的控制器其实就是充当了路由的角色

路由的效果

现在我们还没看源码,不知道其实现细节,但是实现表现是这样的:

http://www.example.com/#/state1http://www.example.com/#/state2

这里state1,和state2便是不同的View了,以我们这个例子来说,如果index是首页列表视图,detail便是某一篇博客的视图了,所以

http://www.example.com/#/index——首页列表http://www.example.com/#/detail——具体博客

这个是路由的基本功能,想一想,假如,我们现在各个View已经写开了,view与view直接数据可以由localstorage通信

但是全局性各个状态,全局共用方法还得放到控制器里面,这里对应的就是路由里面(比如我一个全局的showLoading方法)

说了这么多也没意义,我们先将detail的view做了,再看他是怎么路由的

切换视图

其实这个代码,我处理的的有问题,我们上面的列表中的每一个列表项其实应该对应一个model

我在过程中却将model与dom的映射关系给丢了,比如我现在点击一个列表项,我需要知道我现在对应的是哪一个model

这里补救方案是给dom上增加一个索引index,点击时候根据index获取当前索引,但是这不是长久之计,后面需要更好的办法

1 for (var i = 0, len = models.length; i < len; i++) {2   models[i].index = i;3   html += this.itemTmpt(_.extend(models[i].toJSON(), {index: i}));4 }

于是我们每一个dom上面就会多出一个index的属性,哎,这里感觉不是太好啊

现在点击各个列表后会给相关model增加一个model的属性:

然后我们这里初略的重新渲染下页面,这里稍微修改下代码:

1   2   3   4   
5 6
7
8
9 19 20 21
22
23
24
25 44 67 80 81 82 83 84 197 198
完整的代码

这个代码里面,我们点击其中一个list-item就会显示我们博客正文,但是问题马上就来了

现在的问题

做到现在我们程序大概的逻辑也出来了,当然,问题也出来了:

① 我从首页来到了博客页,但是大哥,我该怎么回去啊???

② 我们的程序全部在demo这个页面里面,个人感觉很乱啊!!!现在是两个view就这样,万一我有20个view我是不是要哭!!!

③ 我们最开始的view时index的,比如上面的回退按钮与“博客园”三个字,我们在博客页整个view应该隶属于自己的,但是这是嵌套的,很乱

要解决以上问题,我觉得是时候引入require已经路由的知识点了

require这个库,我们后面有时间在一起深入学习下,这里只是使用其核心的功能,简单起见,模板我就全部写在demo中,不予分离了

引入路由功能

我们当然想在页面中点击某个按钮来导向某个方法了,比如我们上面进入了detail博客页,我现在先回到首页,我可以后退

1 var App = Backbone.Router.extend({ 2   routes: { 3     "": "index",    // #index 4     "index": "index",    // #index 5     "detail": "detail"    // #detail 6   }, 7   index: function () { 8     var index = new Index(); 9   }10 });11 12 var app = new App();13 Backbone.history.start();

这么小心一段代码加上后,就会在页面url锚点#后面的字符变了后执行相关的方法,显然我们这里需要更多的信息,或者说,我们的路由应该担任整个view通信的功能

首先,我们这里将index与detail两个view的模板完全独立,这里用了比较图的办法,全部清除html,但是现在确实可以跳转了

1   2   3   4   
5 6
7
8
9 19 20 21

22 index 23

24
25
26
27
28 48 71 84 85 86 87 88 212 213
View Code

现在问题又来了,我点击其中一个一个列表项目时候,我就执行了render方法,现在我不想这么做了,我想将其加载数据的逻辑放到detail里面去

并且通过路由的方式实现,但是我们数据model的传递(这里没有使用localstorage)需要用路由来实现

1   2   3   4   
5 6
7
8
9 19 20 21
22
23
24
25 45 68 81 82 83 84 85 248 249
重要版本

如此一来,我们的基本逻辑结束,马上我们又面临其它问题:

① 我们每个view的initialize方法都会被传入app接口

② 我们每个view都有一些重复的代码(比如this.app = app),而我们各个view没有好的状态控制

比如我们页面的create阶段,load阶段,show阶段,hide阶段,这些都需要事件进行处理,这里却没法一一关注

③ 可以看到,我们的路由居然还充当了很多传递数据的作用,但是我们并不应该这样写

④ 各位是否感觉我们的路由仍然太简陋,我们的程序很容易报错呢?

以上这些问题暂时留给各位思考,我下次使用require将我们的view分离先,本来今天想做的,但是感觉干不动了

结语

今天的内容暂时到此,本来想做个简单的例子来着,结果做着做着居然又涉及到这么多东西了,我们下次将这个单页应用完成,并且开始源码学习:

① 细化App(路由/控制器),让其完成更多的工作

② 引入require分离view

③ 创建view父类供各个view使用

④ 源码细节实现分析

总的来说,Backbone的阅读应该比原来碰到的框架难,原来那些框架只不过是基础库,但是Backbone涉及到了思想

这种框架性东西,我们后面还得花大力气消化,今天暂时到此

转载地址:http://tpcta.baihongyu.com/

你可能感兴趣的文章
Vue------第二天(计算属性、侦听器、绑定Class、绑定Style)
查看>>
dojo.mixin(混合进)、dojo.extend、dojo.declare
查看>>
Python 数据类型
查看>>
iOS--环信集成并修改头像和昵称(需要自己的服务器)
查看>>
PHP版微信权限验证配置,音频文件下载,FFmpeg转码,上传OSS和删除转存服务器本地文件...
查看>>
教程前言 - 回归宣言
查看>>
PHP 7.1是否支持操作符重载?
查看>>
Vue.js 中v-for和v-if一起使用,来判断select中的option为选中项
查看>>
Java中AES加密解密以及签名校验
查看>>
定义内部类 继承 AsyncTask 来实现异步网络请求
查看>>
VC中怎么读取.txt文件
查看>>
如何清理mac系统垃圾
查看>>
企业中最佳虚拟机软件应用程序—Parallels Deskto
查看>>
Nginx配置文件详细说明
查看>>
怎么用Navicat Premium图标编辑器创建表
查看>>
Spring配置文件(2)配置方式
查看>>
MariaDB/Mysql 批量插入 批量更新
查看>>
ItelliJ IDEA开发工具使用—创建一个web项目
查看>>
solr-4.10.4部署到tomcat6
查看>>
切片键(Shard Keys)
查看>>