Backbone官方案例Todos分析


$(function(){
  //Model模块
  var Todo = Backbone.Model.extend({
    //默认值,初始化字段
    defaults: function() {
      return {
        title: "empty todo...",
        order: Todos.nextOrder(),
        done: false
      };
    },
    //  将任务完成的状态设置为相反状态
    toggle: function() {
      this.save({
        done: !this.get("done")
      });
    }

  });

  //Collection模块
  var TodoList = Backbone.Collection.extend({
    //Collection的模型名称为todo
    model: Todo,
      //把todo-backbone储存到本地
    localStorage: new Backbone.LocalStorage("todos-backbone"),
      //获取已经完成任务的
    done: function() {
      return this.where({done: true});
    },
      //获取没有完成任务的
    remaining: function() {
      return this.where({done: false});
    },
      //获取下一个插入的编号
    nextOrder: function() {
      if (!this.length) return 1;
      return this.last().get('order') + 1;
    },
      //内置函数,用于给backbone排序,参数是以order排序
    comparator: 'order'

  });
  var Todos = new TodoList;

  //View模块
  //Dom节点的绑定、插入等操作
  var TodoView = Backbone.View.extend({
    //把template模板中获取到的html代码放在这个标签之中
    tagName:  "li",
    //  设置对应模板
    template: _.template($('#item-template').html()),
    //  绑定事件
    events: {
      "click .toggle"   : "toggleDone",
      "dblclick .view"  : "edit",
      "click a.destroy" : "clear",
      "keypress .edit"  : "updateOnEnter",
      "blur .edit"      : "close"
    },
    //  初始化函数,设置对model的监听,用户view之间的通信
    initialize: function() {
      this.listenTo(this.model, 'change', this.render);
      this.listenTo(this.model, 'destroy', this.remove);
    },
    //渲染函数,用户渲染数据到模板中,设置一些全局函数
    render: function() {
      this.$el.html(this.template(this.model.toJSON()));
      this.$el.toggleClass('done', this.model.get('done'));
      this.input = this.$('.edit');
      return this;
    },
    //  控制任务完成或者未完成
    toggleDone: function() {
      this.model.toggle();
    },
    //修改编辑任务时的样式
    edit: function() {
      this.$el.addClass("editing");
      this.input.focus();
    },
    //关闭编辑,并把修改内容同步到界面
    close: function() {
      var value = this.input.val();
      if (!value) {
        this.clear();
      } else {
        this.model.save({title: value});
        this.$el.removeClass("editing");
      }
    },
    //按回车则编辑关闭
    updateOnEnter: function(e) {
      if (e.keyCode == 13) this.close();
    },
    //从local Storage中删除一个条目
    clear: function() {
      this.model.destroy();
    }

  });
  //显示所有任务列表,显示完成多少、未完成多少的列表状态以及任务的添加
  var AppView = Backbone.View.extend({

    //绑定页面上的DOM节点
    el: $("#todoapp"),
    //统计数据模板
    statsTemplate: _.template($('#stats-template').html()),
    //  绑定事件
    events: {
      "keypress #new-todo":  "createOnEnter",
      "click #clear-completed": "clearCompleted",
      "click #toggle-all": "toggleAllComplete"
    },
    //包括事件的绑定以及数据的读取,操作完成之后调用Todos.fetch()
    initialize: function() {
      this.input = this.$("#new-todo");
      this.allCheckbox = this.$("#toggle-all")[0];
      //监听Collection,一有变动就会重新渲染,以达到实时交互的效果
      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');
      //会将数据同步到服务器端→local storage,然后调用了reset方法
      //  而reset绑定了addAll,接下来调用addAll
      //  addAll调用了addOne,在addOne里面实例化了TodoView,而这个类就是主要用数据的同步然后显示的
      //  addOne里面初始化了render事件,一旦model改变就立刻调用render进行重绘
      Todos.fetch();
    },

    //更新当前任务列表的状态
    render: function() {
      var done = Todos.done().length;
      var remaining = Todos.remaining().length;

      if (Todos.length) {
        this.main.show();
        this.footer.show();
        this.footer.html(this.statsTemplate({done: done, remaining: remaining}));
      } else {
        this.main.hide();
        this.footer.hide();
      }
      //根据剩余多少未完成确定标记全部完成的checkbox的显示
      this.allCheckbox.checked = !remaining;
    },

    //添加一个任务到页面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);
    },

    //创建任务,将数据保存到local Storage中
    createOnEnter: function(e) {
      if (e.keyCode != 13) return;
      if (!this.input.val()) return;
      //创建一个对象之后会动态调用Todos的add方法,该方法绑定addOne
      Todos.create({title: this.input.val()});
      this.input.val('');
    },

    //去掉所有已完成的任务
    clearCompleted: function() {
      _.invoke(Todos.done(), 'destroy');
      return false;
    },
    //处理页面点击标记全部完成按钮
    toggleAllComplete: function () {
      var done = this.allCheckbox.checked;
      Todos.each(function (todo) { todo.save({'done': done}); });
    }

  });

  //网页加载的入口,实例化之后会调用构造函数initialize,以及绑定事件到todo上
  var App = new AppView;

});
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值