`
zccst
  • 浏览: 3319179 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

backbone实例Todo源码赏析

阅读更多
作者:zccst
Todo实例花了我两天多的事件,为了下次再忘记,决定记录下来:
$(function(){
/******************** 模型-集合 ********************/
  var Todo = Backbone.Model.extend({
    defaults:function(){//defaults是函数
      return {title:'apple', order:Todos.nextOrder(), done:false};
    },
    initialize:function(){
      if(!this.get("title")){ this.set({title:this.defaults().title}); }
    },
    validate:function(){
      //console.log(this);//alert('validate');
    },
    toggle:function(){//每次取反
      //model变,那么Todos也变,触发Collection的all事件(不是reset)
      this.save({done:!this.get('done')});
    }
  });

  var TodoList = Backbone.Collection.extend({
    model:Todo,
    localStorage:new Backbone.LocalStorage("todos-backbone-my"),//存储
    //默认没有,如果定义了,则被用来维护集合在正确的顺序
    comparator:function(todo){
      return todo.get("order");//使用order作为排序基准。order
    },
    done:function(){//选择done字段为true的集合
      //filter是underscore提供的
      return this.filter(function(todo){return todo.get("done");});
    },
    remaining:function(){
      //underscore提供,排除this中的this.done()元素列表
      return this.without.apply(this, this.done());
    },
    nextOrder:function(){//返回该元素的下一个元素序号
      if(!this.length) return 1;
      //underscore提供,获取最后一个元素的order值再加1
      return this.last().get("order") + 1;
    }
  });
  var Todos = new TodoList;//创建一个名叫Todos的全局集合列表

/******************** 视图 ********************/
  var TodoView = Backbone.View.extend({
    tagName : "li",//el:"todo-list",
    template:_.template($("#item-template").html()),
    events:{
      'click .toggle'  : 'toggleDone',   //点击切换,选中状态
      'dbclick .view'  : 'edit',         //双击编辑
      'blur .edit'     : 'close',        //双击编辑后,失去焦点
      'keypress .edit' : 'updateOnEnter',//双击编辑后,按enter键 编辑成功
      'click a.destroy': 'clear'         //点击删除
    },
    initialize:function(){//model也就两个事件
      this.listenTo(this.model, 'change', this.render);
      this.listenTo(this.model, 'destroy', this.remove);
    },
    render:function(){
      //console.log(this.model);
      this.$el.html(this.template(this.model.toJSON()));
      this.$el.toggleClass("done",this.model.get("done"));
      this.input = $(".edit");//始终指向当前被点击的行
      return this;
    },
    toggleDone:function(){//点击切换选中状态
      this.model.toggle();
    },
    edit:function(){//双击编辑
      this.$el.addClass("editing");
      this.input.focus();
    },
    close:function(){//双击编辑后,input失去焦点
      var value = this.input.val();
      if(!value){
        this.clear();
      }else{
        this.model.save({title:value});//直接save,不需要set啊
        this.$el.removeClass("editing");
      }
    },
    updateOnEnter:function(e){//双击编辑后,按enter键 编辑成功
      if(e.keyCode == 13) this.close();
    },
    clear:function(){//点击删除
      this.model.destroy();//先触发destroy,后触发change事件
    }
  });

  var AppView = Backbone.View.extend({
    //el:"#todoapp",el表示element,如果是id,需要#ID
    el:$("#todoapp"),
    statsTemplate : _.template($("#stats-template").html()),
    events:{//events是对象
      'keypress #new-todo'     : 'createOnEnter',     //创建新的
      'click #toggle-all'      : 'toggleAllComplete', //全选
      'click #clear-completed' : 'clearCompleted'     //清空
    },
    initialize:function(){
      this.input = this.$("#new-todo");
      this.allCheckbox = this.$("#toggle-all")[0];
      //触发add事件的方法 :create, fetch, add, set
      this.listenTo(Todos, 'add', this.addOne);  
      //this.listenTo(Todos, 'reset', this.addAll);//触发reset :reset
      //只控制了footer模板,查询计算已选和未选个数
      //this.listenTo(Todos, 'all', this.render);  
      this.listenTo(Todos, 'change', this.render);
      this.listenTo(Todos, 'add', this.render);
      this.listenTo(Todos, 'remove', this.render);
      this.footer = this.$("footer");
      this.main   = this.$("#main");
      //化学效应,先驻足半小时,过一遍backbone的事件监听流程
      Todos.fetch();//没触发change,reset,remove事件,触发了add事件。{reset:true}触发reset事件
    },
    render:function(){//更新当前任务列表的状态
      var done = Todos.done().length;           //已选中的集合
      var remaining = Todos.remaining().length; //未选中的集合
      if( Todos.length ){                       //Todos.length全部的集合
        this.main.show();
        this.footer.show();
        this.footer.html(this.statsTemplate({done:done,remaining:remaining}));
      }else{
        this.main.hide();
        this.footer.hide();
      }
      //console.log(done,remaining);
      this.allCheckbox.checked = !remaining;
    },
    createOnEnter:function(e){//在events中绑定,所以参数是event
      if(e.keyCode != 13) return;
      if(!this.input.val()) return;
      //触发集合的add事件(绑定了addOne方法)
      Todos.create({'title':this.input.val()});
      this.input.val("");
    },
    toggleAllComplete:function(){
      var done = this.allCheckbox.checked;
      Todos.each(function(todo){ todo.save({'done':done}); });
    },
    clearCompleted:function(){
      //清除所有被选中的(done:true的)
      //_.invoke(Todos.done(), 'destroy');
      var arr = Todos.done();for(var item in arr){ arr[item].destroy();};//替换
      return false;
    },
    addOne:function(todo){//在initialize中绑定,所以参数是model
      var view = new TodoView({model:todo});
      //Todo的render方法必须主动调
      this.$("#todo-list").append(view.render().el);
    },
    addAll:function(){
      Todos.each(this.addOne, this);
    }
  });
var AppView = new AppView();
});



批注:AppView中initialize的add, change, remove 加起来基本可以相当于all事件了。

reset的使用场景:
1,调用fetch()方法时加了{reset:true}时触发reset事件
2,直接reset({...});时触发reset事件



<div id="todoapp">
    <header>
        <h1>Todos演示</h1>
        <input id="new-todo" type="text" placeholder="请输入您想做的事情?">
    </header>

    <section id="main">
        <!--for 属性规定 label 与哪个表单元素绑定-->
        <input id="toggle-all" type="checkbox">
        <label for="toggle-all">全选</label>

        <ul id="todo-list"></ul>
    </section>

    <footer>
      <a id="clear-completed">全部清空</a>
      <div id="todo-count"></div>
    </footer>
</div>

<div id="instructions">
    双击编辑一个todo.
</div>

<div id="credits">
    由<a href="http://www.sogou.com">某某</a>创建。
    <br />Rewritten by: <a href="http://addyosmani.github.com/todomvc">TodoMVC</a>.
</div>


<!-- Templates -->
<!-- 每一项的模板 -->
<script type="text/template" id="item-template">
    <div class="view">
        <input class="toggle" type="checkbox" <%= done ? 'checked="checked"' : '' %> />
        <label><%- title %></label>
        <a class="destroy"></a>
    </div>
    <input class="edit" type="text" value="<%- title %>" />
</script>

<!-- 底部模板 -->
<script type="text/template" id="stats-template">
    <% if (done) { %>
      <a id="clear-completed"> 有 <%= done %> 个被选中,立即清除 </a>
    <% } %>
    <div class="todo-count">还有 <b><%= remaining %></b> 个未被选中</div>
</script>




如果您觉得本文的内容对您的学习有所帮助,您可以微信:
分享到:
评论

相关推荐

    backbone官方Todo示例

    backbone官方Todo示例内含自己详细注释,建议运行之后打开浏览器调试同步学习。

    backbone官方Todo示例_修正

    "backbone官方Todo示例_修正"是一个很好的学习资源,它演示了如何使用Backbone.js来构建一个简单的待办事项管理应用。 1. **模型(Model)**:在Backbone中,模型是应用程序数据的核心,通常对应于服务器上的JSON对象...

    基于backbone框架的TODO实例

    在这个"基于Backbone框架的TODO实例"中,我们可以学习到如何利用Backbone来创建一个简单的任务管理应用。 1. **Backbone的基本组件** - **Model**: 是数据存储的核心,负责处理数据的CRUD(创建、读取、更新、删除...

    Backbone-Todo:使用 Backbone 的 Todo 应用程序

    Backbone-Todo 我使用 Backbone 创建了这个 Todo。 本地存储由backbone.localStorage js 完成。 使用 Bootstrap 3.0 进行设计,模板使用 Underscore.js。

    Backbone-Todo:简单的主干 Todo 应用程序

    **Backbone-Todo: 简单的主干Todo应用程序** `Backbone-Todo` 是一个基于 `Backbone.js` 框架构建的简单待办事项管理应用。`Backbone.js` 是一个轻量级的JavaScript库,主要用于构建结构化的前端应用。它提供了模型...

    透过源码学前端 之 Backbone 一

    任何Backbone对象都可以触发和监听事件,使得组件间可以通过事件来传递信息,而不是直接依赖于对象实例。 在压缩包中的"backbone分析第一部分.js"文件,很可能是对Backbone源码的一部分分析。可能包含的内容有对...

    backbone实例demo

    在“backbone实例demo”中,我们可以看到如何结合其他技术,如Seajs和Zepto,来构建一个实际的项目。 Seajs是一个流行的模块化JavaScript加载器,类似于AMD(Asynchronous Module Definition)规范的RequireJS。它...

    backbone-todo:骨干全部演示

    《Backbone.js 全面解析:以Todo应用为例》 Backbone.js,作为一个轻量级的JavaScript库,是前端开发中的重要工具,尤其在构建复杂、数据驱动的应用时显得尤为实用。本文将以"backbone-todo"为例,深入剖析Backbone...

    backbone 实例

    让我们深入探讨一下Backbone的API及其在实际应用中的实例。 **一、Backbone.Model** Backbone.Model是数据存储的基础,它可以视为后端API与前端展示之间的桥梁。Model包含数据和业务逻辑,提供get、set、save等...

    backbone-todo-app

    Backbone-Todo-App 此应用程序展示了如何将客户端的和服务器端的与以创建丰富的交互和协作应用程序,例如待办事项列表管理器. 代码 应用程序的大部分前端逻辑很大程度上基于。 我们编写了一个将 Pusher 和 Backbone...

    backbone源码解析

    backbone源码解析,写得非常好,下载了你不后悔

    backbone 源码+API

    在"backbone 源码+API"中,我们有两个主要的组成部分:`backbone-master.zip`和`underscore-master.zip`。 首先,`backbone-master.zip`包含了Backbone.js的源码。Backbone.js的源码对于深入理解其工作原理至关重要...

    《Node应用程序构建:使用MongoDB和Backbone》 源码

    《Node应用程序构建:使用MongoDB和Backbone》是一本深入探讨使用Node.js、MongoDB以及Backbone.js构建高效网络应用的书籍。源码提供给读者更直观的学习体验,通过实际操作加深理论理解。以下是该书涉及的主要知识点...

    requirejs todo 实例

    通过这个Todo实例,我们可以看到RequireJS如何帮助我们组织代码,按需加载模块,管理依赖关系,使得代码更加清晰、可维护。同时,它也允许我们在多个模块之间共享和重用代码,提高了开发效率。在实际项目中,我们...

    backbone-todo-first

    - 创建一个`TodoList`集合,包含多个`Todo`实例,并可能有一个URL用于与服务器同步数据。 - 实现一个`TodoView`,展示单个待办事项,包括标题和复选框,以及响应用户的添加、删除和完成待办事项的操作。 - 可能有一...

    backbone_todo:主干全部

    "backbone_todo"是一个基于Backbone.js实现的TodoMVC示例应用,它展示了如何利用Backbone.js来创建一个简单的待办事项管理工具。 首先,我们来深入了解一下Backbone.js。Backbone.js的核心概念是它对数据模型...

    backbone框架在实例中的应用~简单易学

    在这个"backbone框架在实例中的应用~简单易学"的主题中,我们将深入探讨Backbone的关键特性及其在实际项目中的应用。 首先,Backbone的Model是数据管理的核心。它封装了应用程序的数据,提供了数据的CRUD(创建、...

    backbone官方实例

    在这个"backbone官方实例"中,我们可以深入理解Backbone.js的工作原理和实际应用。 1. **模型(Model)**: Backbone中的模型是应用数据的核心,负责存储和管理数据。它与服务器端进行交互,可以触发变更事件来通知...

    backbone-todo:用 Backbone 编写的简单待办事项列表

    在"backbone-todo"项目中,我们将会探讨如何利用Backbone.js来创建一个简单的待办事项列表。这个应用非常适合初学者学习MVC概念以及Backbone.js的基础用法。 首先,Backbone.js的核心概念包括Model、View、...

    Backbone_Todo_App

    在"Backbone_Todo_App"这个项目中,我们将深入探讨如何使用Backbone.js来创建一个待办事项管理应用。这个应用展示了Backbone.js的核心特性,包括模型(Models)、视图(Views)、集合(Collections)和路由(Routers...

Global site tag (gtag.js) - Google Analytics