【转】Backbone标准例子——通讯录

参考:http://z2009zxiaolong.iteye.com/blog/1847833

感觉不错的例子,模型、视图、路由等知识点都用到了:),将此文中的源码转载如下:

备注:http://dmyz.org/archives/598 这篇教程也不错,讲的很清楚。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Backbone通讯录</title>
  <link rel="stylesheet" href="css/application.css" type="text/css" charset="utf-8">
</head>
<body>
  <header id="header"><h1>Backbone通讯录</h1></header>
  <article id="article"></article>
</body>
  <script src="js/lib/jquery.js" type="text/javascript" charset="utf-8"></script>
  <script src="js/lib/underscore.js" type="text/javascript" charset="utf-8"></script>
  <script src="js/lib/backbone.js" type="text/javascript" charset="utf-8"></script>
  <script src="js/lib/backbone-localstorage.js" type="text/javascript" charset="utf-8"></script>
  <script src="js/application.js" type="text/javascript" charset="utf-8"></script>

  <!-- 联系人 -->
  <script type="text/template" id="tpl-item">
      <%= (name ? name : "<i>无名</i>") %>
  </script>

  <!-- 左边的侧边条,包括联系人列表 -->
  <script type="text/template" id="tpl-sidebar">
    <header>
      <input type="search" placeholder="搜索" results="0" incremental="true" autofocus>
    </header>
    <div class="items"></div>
    <footer>
      <button>新建联系人</button>
    </footer>
  </script>

  <!-- 显示联系人详细信息 -->
  <script type="text/template" id="tpl-show">
    <header>
      <a class="edit">编辑</a>
    </header>
    <div class="content">
      <p><label>姓名:<%= name %></label></p>
      <p><label>邮箱:<%= email %></label></p>
    </div>
  </script>

  <!-- 编辑联系人信息 -->
  <script type="text/template" id="tpl-edit">
    <header>
      <a class="save">保存</a>
      <a class="delete">删除</a>
    </header>
    <div class="content">
      <form>
        <label>
          <span>姓名:</span>
          <input type="text" name="name" value="<%= name %>">
        </label>
        <label>
          <span>邮箱:</span>
          <input type="email" name="email" value="<%= email %>">
        </label>
        <button>保存</button>
      </form>
    </div>
  </script>
</html>
(function($) {
  $(document).ready(function() {
    var Contact = Backbone.Model.extend({
      defaults: {
        name: ‘‘,
        email: ‘‘
      },

      validate: function(attrs, options) {
        if (attrs.name == "") {
          return "用户名不能为空!";
        };
      },

      // 用户搜索的辅助方法
      filter: function(query) {
        if (typeof(query) === ‘undefined‘ || query === null || query === ‘‘) return true;
        query = query.toLowerCase();
        return this.get(‘name‘).toLowerCase().indexOf(query) != -1 || this.get(‘email‘).toLowerCase().indexOf(query) != -1;
      }
    });

    var Contacts = Backbone.Collection.extend({
      model: Contact,
      localStorage: new Store(‘my-contacts‘)
    });

    // 单个联系人视图
    var ContactItemView = Backbone.View.extend({
      className: ‘item‘,
      template: _.template($(‘#tpl-item‘).html()),
      events: {
        ‘click‘: ‘select‘
      },

      initialize: function() {
        _.bindAll(this, ‘select‘);
        this.model.bind(‘reset‘, this.render, this);
        this.model.bind(‘change‘, this.render, this);
        this.model.bind(‘destroy‘, this.remove, this);
        if (this.model.view) this.model.view.remove();
        this.model.view = this;
      },

      // 渲染联系人
      render: function() {
        this.$el.html(this.template(this.model.toJSON()));
        return this;
      },

      select: function() {
        appRouter.navigate(‘contacts/‘ + this.model.cid, {
          trigger: true
        });
      },

      active: function() {
        this.$el.addClass(‘active‘);
      },

      deactive: function() {
        this.$el.removeClass(‘active‘);
      }
    });

    // 左边的侧边条视图
    var SidebarView = Backbone.View.extend({
      className: ‘sidebar‘,
      template: _.template($(‘#tpl-sidebar‘).html()),
      events: {
        ‘click footer button‘: ‘create‘,
        ‘click input‘: ‘filter‘,
        ‘keyup input‘: ‘filter‘
      },

      initialize: function() {
        _.bindAll(this, ‘create‘, ‘filter‘);
        this.model.bind(‘reset‘, this.renderAll, this);
        this.model.bind(‘add‘, this.add, this);
        this.model.bind(‘remove‘, this.remove, this);
      },

      // 渲染联系人列表
      render: function() {
        $(this.el).html(this.template());
        this.renderAll();
        return this;
      },

      renderAll: function() {
        this.$(".items").empty();
        this.model.each(this.renderOne, this);
        this.filter();
      },

      renderOne: function(contact) {
        var view = new ContactItemView({
          model: contact
        });
        this.$(".items").append(view.render().el);
      },

      create: function() {
        var contact = new Contact();
        this.model.add(contact);
        appRouter.navigate(‘contacts/‘ + contact.cid + ‘/edit‘, {
          trigger: true
        });
      },

      filter: function() {
        var query = $(‘input‘, this.el).val();
        this.model.each(function(contact, element, index, list) {
          contact.view.$el.toggle(contact.filter(query));
        });
        // this.model.last().view.$el.trigger("click")
      },

      active: function(item) {
        if (this.activeItem) this.activeItem.view.deactive();
        this.activeItem = item;
        if (this.activeItem) this.activeItem.view.active();
      },

      add: function(contact) {
        this.renderOne(contact);
      },

      remove: function(contact) {
        console.log(contact);
      }
    });
    // 显示选择的联系人详细信息
    var ShowView = Backbone.View.extend({
      className: ‘show‘,
      template: _.template($(‘#tpl-show‘).html()),

      events: {
        ‘click .edit‘: ‘edit‘
      },

      initialize: function() {
        _.bindAll(this, ‘edit‘);
      },

      render: function() {
        if (this.item) this.$el.html(this.template(this.item.toJSON()));
        return this;
      },

      change: function(item) {
        this.item = item;
        this.render();
      },

      edit: function() {
        if (this.item) appRouter.navigate(‘contacts/‘ + this.item.cid + ‘/edit‘, {
          trigger: true
        });
      }
    });

    // 编辑选择的联系人
    var EditView = Backbone.View.extend({
      className: ‘edit‘,
      template: _.template($(‘#tpl-edit‘).html()),

      events: {
        ‘submit form‘: ‘submit‘,
        ‘click .save‘: ‘submit‘,
        ‘click .delete‘: ‘remove‘
      },

      initialize: function() {
        _.bindAll(this, ‘submit‘, ‘remove‘);
      },

      render: function() {
        if (this.item) this.$el.html(this.template(this.item.toJSON()));
        return this;
      },

      change: function(item) {
        this.item = item;
        this.render();
      },

      submit: function() {
        this.item.set(this.form());
        this.item.save();
        appRouter.navigate(‘contacts/‘ + this.item.cid, {
          trigger: true
        });
        return false;
      },

      form: function() {
        return {
          name: this.$(‘form [name="name"]‘).val(),
          email: this.$(‘form [name="email"]‘).val()
        };
      },

      remove: function() {
        this.item.destroy();
        this.item = null;
        appRouter.navigate(‘‘, {
          trigger: true
        });
      }
    });

    // 主视图,显示和编辑联系人
    var MainView = Backbone.View.extend({
      className: ‘main stack‘,
      initialize: function() {
        this.editView = new EditView();
        this.showView = new ShowView();
      },

      render: function() {
        this.$el.append(this.showView.render().el);
        this.$el.append(this.editView.render().el);
        return this;
      },

      edit: function(item) {
        this.showView.$el.removeClass(‘active‘);
        this.editView.$el.addClass(‘active‘);
        this.editView.change(item);
      },

      show: function(item) {
        this.editView.$el.removeClass(‘active‘);
        this.showView.$el.addClass(‘active‘);
        this.showView.change(item);
      }
    });

    // 整个页面的视图,管理SiderbarView和MainView两个子视图
    var AppView = Backbone.View.extend({
      className: ‘contacts‘,

      initialize: function() {
        this.sidebar = new SidebarView({
          model: this.model
        });
        this.main = new MainView();
        this.vdiv = $(‘<div />‘).addClass(‘vdivide‘);
        this.model.fetch();
        this.render();
      },

      render: function() {
        this.$el.append(this.sidebar.render().el);
        this.$el.append(this.vdiv);
        this.$el.append(this.main.render().el);
        $(‘#article‘).append(this.el);
        return this;
      },

      show: function(item) {
        this.sidebar.active(item);
        this.main.show(item);
      },

      edit: function(item) {
        this.sidebar.active(item);
        this.main.edit(item);
      }
    });

    // 路由
    var AppRouter = Backbone.Router.extend({
      routes: {
        ‘‘: ‘show‘,
        ‘contacts/:id‘: ‘show‘,
        ‘contacts/:id/edit‘: ‘edit‘
      },

      show: function(id) {
        if (id != undefined) {
          appView.show(this.getContact(id));
        } else {
          appView.show(contacts.first());
        }
      },

      edit: function(id) {
        appView.edit(this.getContact(id));
      },

      getContact: function(id) {
        return contacts.getByCid(id);
      }
    });

    var contacts = new Contacts();
    window.appView = new AppView({
      model: contacts
    });
    window.appRouter = new AppRouter();
    Backbone.history.start();
  });
})(jQuery);
时间: 2024-11-06 23:21:57

【转】Backbone标准例子——通讯录的相关文章

隔行换色(WPF DataGrid 标准例子)

 <DataGrid AlternationCount="2">             <DataGrid.RowStyle>                 <Style TargetType="{x:Type DataGridRow}">                     <Style.Triggers>                         <Trigger Property="

转:backbone.js源码解析:extend、Backbone.View

源:http://www.cnblogs.com/mxw09/archive/2012/07/06/2579329.html backbone版本:0.9.2 1.解析Backbone.Model(Collection | Router | View).extend (1).找到extend的定义 //定义extend函数  var extend = function (protoProps, classProps) {    /*    通常我们以Backbone.XXX.extend的方式建

PHP开发常用函数和必须会的函数总结 --带例子

PHP开发常用函数 在共过开发中,我经常要用到一些PHP函数,有时会不记得,这里把这些常用函数总结到一起.本篇列举了PHP程序员开发中经常用到的php函数.几乎每个函数都有例子,老手可以看看当做温习,新手可以背理论,然后把例子敲他几遍,后面再开发中,开发效率绝对有所提高.例子大多取自w3cschool标准例子和网上的一些资源,部分为个人所写,均经过测试.如果要装载本文,还请注明来源 :http://blog.csdn.net/qq_22327455. 一.检查函数 1.empty() empty

opencv高效访问图像像素(遍历像素的方法总结)

一.Accessingpixel values访问像素值.(用类自带的方法:方便,但效率不高) 1.      cv::Mat has the a templatemethod at(int y, int x) 用法image.at<cv::Vec3b>(j,i)[channel]= value; 注意事项:the programmer needs to specify the return type that is expected(需认为指定返回值类型),一般使用type cv::Vec3

ANDROID 中设计模式的采用--结构型模式

结构型模式中的适配器模式.外观模式.装饰模式.代理模式都属于包装模式,都是对另外的类或对象的包装,只是各自的意图不同. 适配器模式通过对另外的类或对象的包装,将其接口转换为用户期望的接口,达到接口适配的目的. 外观模式是对包装的一组类或对象提供一个高层接口,意图是简化接口,使系统更加容易使用. 装饰模式的意图是在不改变包装对象接口的情况下为其增加另外的功能或职责. 代理模式的意图是通过对包装对象的包装以便控制对包装对象的访问. 适配器模式.外观模式对客户提供的接口与其包装类的接口有所不同,也就是

移动端缓存增量更新

移动端缓存增量更新 在app的时候, 为了用户体验, 一般都会引入缓存来加速app的运行. 而缓存这东西用的好则是倚天剑, 用的不好, 容易带进脏数据. 这里来说说移动端缓存增量更新的设计思想. 以通讯录为例子. 通讯录 场景1 : app上没有任何缓存记录. 场景2 : app上存在缓存记录, 但是有一段时间没有使用改app, 不能确保缓存为最新. 场景3:  app正在使用缓存. 在上述三个场景中, 最麻烦的就是场景2, 因为可能会出现server在app不使用的时间段对通讯录中的信息进行了

编写Unity3D着色器的三种方式

不管你会不会写Unity3D的shader,估计你会知道,Unity3D编写shader有三种方式,这篇东西主要就是说一下这三种东西有什么区别,和大概是怎样用的. 先来列一下这三种方式: fixed function shader vertex and fragment shader surface shader 为什么Unity3D要提供三种shader的编写方式呢?那是因为三种方式的编写的难易度有区别,对应着不同的使用人群.其实我觉得这是Uniy3D想得有点多了,着色器不单止是为了实现效果,

201704 创建财务凭证函数

从老司机那了解到创建财务凭证就只有两个函数,用的多的就是 BAPI_ACC_DOCUMENT_POST. 另外,今天发现下另外一个, 418-419 要完成F110 预付款功能的开发,得抓紧时间了. 以下转自[http://blog.csdn.net/trassion/article/details/8267953] http://www.soujigu.com/blog_76943.html http://blog.csdn.net/longgerr/article/details/59582

代码生成器原理

今天突然想玩玩这个..搞搞代码生成器,今天把原理发出来..写好Demo陆续更新 整个架设思路分的4个部分:A:底层物理数据库层,主要是存储数据用的.B:数据库访问层,主要是为了写一套代码可以跑在多种数据库上.C:一些辅助工具.基础组件,是为了加强自动产生代码的功能.简化代码复杂性,进行合理的分工协作用的.D:自动生成的代码部分,用PowerDesigner设计简洁明了.易于沟通理解,代码分自动生成及人工部分,为了重复生成方便. 详细功能部分只要是分12个部分来讲解,分别如下:01:我业务里需要的