在前两篇文章中,我们已经对这个todos的功能、数据模型以及各个模块的实现细节进行了分析,这篇文章我们要对前面的分析进行一个整合。
首先让我们来回顾一下我们分析的流程:先对页面功能进行了分析,然后又分析了数据模型,最后又对view的功能和代码进行了详解。你是不是觉得这个分析里面少了点什么?没错,就知道经验丰富的你已经看出来了,这里面少了对于流程的分析。这篇文章就对整体流程进行分析。
所以从我的分析中可以看的出来,我是先对各个原材料进行分析,然后再整体的分析(当然前提是我是理解流程的),这并不是分析代码的唯一方法,有时我也会采用跟着流程分析代码的方法。当然还有很多其他的分析方法,大家都有自己的套路嘛。
下面简单的说说流程分析的方法。记得多年前在学vb的时候,分析一个完整项目代码的时候,习惯从程序的入口点开始分析。虽然web网站和桌面软件的实现不同,但是大致思路是一样的(同时也有网站即软件的说法,在RESTful架构中)。所以我们要先找到网站的入口点所在。
和桌面应用项目的分析一样,网站的入口点就在于网页加载的时候。对于todos,自然就是在页面加载完之后执行的操作了,然后就看到下面的代码。
首先是对AppView的一个实例化:
var App = new AppView;
实例化,自然就会调用构造函数:
//在初始化过程中,绑定事件到Todos上,
//当任务列表改变时会触发对应的事件。
//最后从localStorage中fetch数据到Todos中。
initialize: function() {
this.input = this.$("#new-todo");
this.allCheckbox = this.$("#toggle-all")[0];
this.listenTo(Todos, 'add', this.addOne);
this.listenTo(Todos, 'reset', this.addAll);
this.listenTo(Todos, 'all', this.render);
this.footer = this.$('footer');
this.main = $('#main');
Todos.fetch();
},
注意其中的Todos.fetch()方法,前面说过,这个项目是在客户端保存数据,所以使用fetch方法并不会发送请求到服务器。另外在前面关于collection的单独讲解中我们也知道了collection中调用fetch方法之后就会触发reset这个方法。所以现在流程走向reset——>addAll这个方法。
来看addAll这个方法:
// 添加一个任务到页面id为todo-list的div/ul中
addOne: function(todo) {
var view = new TodoView({model: todo});
this.$("#todo-list").append(view.render().el);
},
// 把Todos中的所有数据渲染到页面,页面加载的时候用到
addAll: function() {
Todos.each(this.addOne, this);
},
在addAll中调用addOne方法,关于Todos.each很好理解,就是语法糖(简化的for循环),到此,加载页面的整个流程也就完成了。关于addOne方法的细节下面介绍。
然后再来看添加任务的流程,一个良好的代码命名风格始终是让人满心欢喜的。因为很显然,添加一个任务,自然就是addOne,其实你看events中的绑定也能知道,先看一下绑定:
// 绑定dom节点上的事件
events: {
"keypress #new-todo": "createOnEnter",
"click #clear-completed": "clearCompleted",
"click #toggle-all": "toggleAllComplete"
},
这里并没有addOne方法的绑定,但是却有createOnEnter,语意其实一样的。来看主线,createOnEnter这个方法:
//创建一个任务的方法,使用backbone.collection的create方法。将数据保存到localStorage,这是一个html5的js库。需要浏览器支持html5才能用。
createOnEnter: function(e) {
if (e.keyCode != 13) return;
if (!this.input.val()) return;
//创建一个对象之后会在backbone中动态调用Todos的add方法,该方法已绑定addOne。
Todos.create({title: this.input.val()});
this.input.val('');
},
注释已写明,Todos.create会调用addOne这个方法。由此顺理成章的来到addOne里面:
//添加一个任务到页面id为todo-list的div/ul中
addOne: function(todo) {
var view = new TodoView({model: todo});
this.$("#todo-list").append(view.render().el);
},
在里面实例化了一个TodoView类,前面我们说过,这个类是主管各个任务的显示的。具体代码就不细说了。
有了添加再来看更新,关于单个任务的操作,我们直接找TodoView就ok了。所以直接找到
// 为每一个任务条目绑定事件
events: {
"click .toggle" : "toggleDone",
"dblclick .view" : "edit",
"click a.destroy" : "clear",
"keypress .edit" : "updateOnEnter",
"blur .edit" : "close"
},
其中的edit事件的绑定就是更新的一个开头,而updateOnEnter就是更新的具体动作。所以只要搞清楚这俩方法的作用一切就明了了。这里同样不用细说。
在往后还有删除一条记录以及清楚已有记录的功能,根据上面的分析过程,我想大家都很容易的去‘顺藤模瓜’。
关于Todos的分析到此就算完成了。
在下一篇文章中我们将一起来学习通过web.py来搭建web服务器,以及简单的数据库的使用。
导航
- 上一章 07 实战演练:todos分析(二)view的应用
- 下一章 09 后端环境搭建:web.py的使用