• 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
  • 相关阅读:
    软件的结构
    SpringMVC返回值类型及响应数据类型
    mybatis学习日记3
    面试八
    面试七
    微信小程序实例源码大全下载
    dot.js模板引擎,避免大量拼接字符串
    前端重构方案了解一下
    微信小程序开发基础教程
    如何让签到成为提升用户活跃度的利器
  • 原文地址:https://www.cnblogs.com/jiangcheng-langzi/p/7223239.html
Copyright © 2020-2023  润新知