Backbone.js之Todo源码浅析

Posted Jinus

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Backbone.js之Todo源码浅析相关的知识,希望对你有一定的参考价值。

相信每个接触了解过backbone的人都知道todo,网上的关于它的分析教程也都分析乱了。但是,知识只有自己学习领悟才是自己的,话不多说,正文开始。

在分析todo的源码之前,首先我们要知道todo具有哪些功能。todo类似于备忘录一样,其界面如下图:

1.当我们在输入框完成输入item时,按下enter键,下方会出现输入的内容item,item是一个li。

2.在所有item的最上面是一个全选checkbox。

3.每一个item是一个checkbox,当勾选任一行item时,则该行的内容会被删除线划掉,同时最下面的item left-1,Clear completed item+1。

4.当鼠标移到item上时,item的末端会出现一个删除符号,点击删除符号,该item即被删除。

简短介绍完todo的基本功能后,开始源码之旅。

todo.js整体长这个样子,如下图:

一个model,一个collection,两个view。

model详见如下:

 1   var Todo = Backbone.Model.extend({
 2     defaults: function() {
 3       return {
 4         title: "empty todo...",
 5         order: Todos.nextOrder(),
 6         done: false
 7       };
 8     },
 9     toggle: function() {
10       this.save({done: !this.get("done")});
11     }
12   });
View Code

默认设置defaults,返回一个list;定义了一个toggle,该触发器会设置保存model的状态。

collection详见如下:

 1  var TodoList = Backbone.Collection.extend({
 2     model: Todo,
 3     localStorage: new Backbone.LocalStorage("todos-backbone"),
 4     done: function() {
 5       return this.where({done: true});
 6     },
 7     remaining: function() {
 8       return this.where({done: false});
 9     },
10     nextOrder: function() {
11       if (!this.length) return 1;
12       return this.last().get(\'order\') + 1;
13     },
14     comparator: \'order\'
15   });
View Code

指定集合TodoList的mode为Todo,存储方式为localStorage,同时定义了done,remaining,nextOrder三个函数,最后指定了todo的排列顺序。

TodoView详见如下:

 1  var TodoView = Backbone.View.extend({
 2     tagName:  "li",
 3     template: _.template($(\'#item-template\').html()),
 4     events: {
 5       "click .toggle"   : "toggleDone",
 6       "dblclick .view"  : "edit",
 7       "click a.destroy" : "clear",
 8       "keypress .edit"  : "updateOnEnter",
 9       "blur .edit"      : "close"
10     },
11     initialize: function() {
12       this.listenTo(this.model, \'change\', this.render);
13       this.listenTo(this.model, \'destroy\', this.remove);
14     },
15     render: function() {
16       this.$el.html(this.template(this.model.toJSON()));
17       this.$el.toggleClass(\'done\', this.model.get(\'done\'));
18       this.input = this.$(\'.edit\');
19       return this;
20     },
21     toggleDone: function() {
22       this.model.toggle();
23     },
24     edit: function() {
25       this.$el.addClass("editing");
26       this.input.focus();
27     },
28     close: function() {
29       var value = this.input.val();
30       if (!value) {
31         this.clear();
32       } else {
33         this.model.save({title: value});
34         this.$el.removeClass("editing");
35       }
36     },
37     updateOnEnter: function(e) {
38       if (e.keyCode == 13) this.close();
39     },
40     clear: function() {
41       this.model.destroy();
42     }
43   });
View Code

AppView详见如下:

 1  var AppView = Backbone.View.extend({
 2     el: $("#todoapp"),
 3     statsTemplate: _.template($(\'#stats-template\').html()),
 4     events: {
 5       "keypress #new-todo":  "createOnEnter",
 6       "click #clear-completed": "clearCompleted",
 7       "click #toggle-all": "toggleAllComplete"
 8     },
 9     initialize: function() {
10       this.input = this.$("#new-todo");
11       this.allCheckbox = this.$("#toggle-all")[0];
12       this.listenTo(Todos, \'add\', this.addOne);
13       this.listenTo(Todos, \'reset\', this.addAll);
14       this.listenTo(Todos, \'all\', this.render);
15       this.footer = this.$(\'footer\');
16       this.main = $(\'#main\');
17       Todos.fetch();
18     },
19     render: function() {
20       var done = Todos.done().length;
21       var remaining = Todos.remaining().length;
22       if (Todos.length) {
23         this.main.show();
24         this.footer.show();
25         this.footer.html(this.statsTemplate({done: done, remaining: remaining}));
26       } else {
27         this.main.hide();
28         this.footer.hide();
29       }
30       this.allCheckbox.checked = !remaining;
31     },
32     addOne: function(todo) {
33       var view = new TodoView({model: todo});
34       this.$("#todo-list").append(view.render().el);
35     },
36     addAll: function() {
37       Todos.each(this.addOne, this);
38     },
39     createOnEnter: function(e) {
40       if (e.keyCode != 13) return;
41       if (!this.input.val()) return;
42       Todos.create({title: this.input.val()});
43       this.input.val(\'\');
44     },
45     clearCompleted: function() {
46       _.invoke(Todos.done(), \'destroy\');
47       return false;
48     },
49     toggleAllComplete: function () {
50       var done = this.allCheckbox.checked;
51       Todos.each(function (todo) { todo.save({\'done\': done}); });
52     }
53   });
View Code

 

以上是关于Backbone.js之Todo源码浅析的主要内容,如果未能解决你的问题,请参考以下文章

Backbone.js - 按顺序插入新的视图项

js 基础 源码学习 backbone 源码阅读

js 基础 源码学习 backbone 源码阅读

js 基础 源码学习 backbone 源码阅读

Backbone.js源码解读(转载)

TODO:Github的使用技巧之同步代码