zoukankan      html  css  js  c++  java
  • Backbone学习总结

    Backbone中文学习文档:http://www.css88.com/doc/backbone/

    来到公司已经有一段时间了,到现在深深的感觉到自己的能力弱的像只周黑鸭,又干涩又黝黑,充满了麻(手麻脑袋也麻)和辣(欲哭无泪),做全栈前后端都得好好学,这不,一个开源项目中出现Backbone,??!??...这是哪个朝代的语言?左打听右询问,才知道是一个上古框架,虽然古老但是很实用也必须要用到(我估计肯定有先东西替代它了,应该会更好用更人性化),懂前端人自然明白。所以各种掰翻找查,在一个做前端姑娘的博客里发现这篇让我看起来很舒服的Backbone,博客我先摘过来,放自己家里习惯点,我在里面也适当加一些自己理解的小东西,算是向这美女姑娘致敬,谢谢,下面会标明出处(不要追究我的法律责任,我不懂法,但是守法),不会白拿的,伸手党确实可恶!

    so,什么way,开始学吧。。。 。。。

    什么是BACKBONE?

        即一个实现了WEB前端的MVC模式的JS库,像JQUERY,angularjs等。

    什么是MVC模式?

        模式:一种解决问题的通用方法

           --设计模式:工厂模式,适配器模式,观察者模式等

           --框架模式:MVC ,MVP,MVVM等

        思想:模型和试图分离,通过控制器来连接他们。关于WEB前端MVC模式。web页面本身就是一个大的VIEW,不容易做到分离操作。其次BACKBONE适合复杂的大型开发。

     图片解析MVC、MVP、MVVM:

    backbone模块组成

        events : 事件驱动方法

        model :数据模型

        collection: 模型集合器

        router :路由器(hash)

        history:开启历史管理

        SYNC : 同步服务器方式

        view : 视图(含事件行为和渲染页面)下面,我们通过一张图,了解一下他们之间的关系。

     collection是model数据的集合。指对多条数据的操作,view是渲染页面的展示。router通过hash指,将对应的数据呈现在不同的view中,当然router必须指定历史管理,历史管理主要是检测hash的变化。模型数据的修改通过ajax的方式,传输到服务器中,进行同步服务器sync。

    backbone的使用

     1:基于jquery(针对试图的实现具体的效果,操作dom),服务器环境,面向对象

     2:基于underscore.js库--作用是:提供了80多种方法,包括数组,对象,事件中的方法,有利于对backbone中的数据模型和集合的操作。

    下面来看一个单个模型实际列子,可自行贴代码测试:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4         <meta charset="utf-8">
     5         <title>测试backbone</title>
     6         <!-- 按照先后顺序,否则会报错 -->
     7         <script  src = "jquery-3.1.0.min.js"></script>
     8         <script  src = "underscore-min.js"></script>
     9         <script  src = "backbone-min.js"></script>
    10         <script type="text/javascript">
    11                      var  model = new  Backbone.Model(); //创建一个backbone的模型实列
    12                      model.set('name' , 'jt');
    13                      console.log( model . get('name'));  //使用set和get方法来获取属性值
    14         </script>
    15 </head>
    16 <body> 
    17 </body>
    18 </html>
    View Code

    控制台打印出来的为:

    下面看下将多个模型数据连接起来的列子,这里不再整个贴代码,看js即可:

    1 var  model_1  =  new  Backbone.Model({'name':'jt'}); //直接赋值进行数据初始化
    2     var  model_2  =  new  Backbone.Model({'name':'lkm'});
    3 
    4     //创建一个数据模型集合
    5     var   models  =  new  Backbone.Collection();
    6     //通过add方法将单个模型添加到模型集合中
    7     models.add(model_1);
    8     models.add(model_2);
    9     console.log(JSON.stringify(models));//JSON解析,将数据集合打印出来

    控制台打印出来的效果为:

    关于模型的扩展

    其实相当于类里面的继承,子类可以使用其继承的方法和属性,在BACKBONE里面,新创建的实列可以使用其模型的方法。看下实列代码:

     1 //模型的构造函数的扩展,相当于继承,则声称的实列可以使用其父类的方法
     2  var   M  =  Backbone.Model.extend({
     3 //第一个参数写实列方法,第二个参数写静态方法
     4         aaa : function(){          //实列方法
     5                    console.log('jt');
     6         }
     7  },{
     8          bbb : function(){           //静态方法
     9                    console.log('lkm');
    10          }                                   
    11  });
    12     var  model =  new M;
    13     model.aaa(); //实列方法,直接使用实列来进行调用
    14     M.bbb(); //静态方法是挂载在构造函数下面的,所以需要使用构造函数来直接调用

    控制台打印结果如下:

    再来看下属性的列子,可自行贴代码进行测试:

    1 var  M =   Backbone.Model.extend({
    2           defaults: {
    3                  name : 'jt'
    4           }
    5       });
    6       var  model = new   M;
    7       console.log(model.get('name'));

    这里defaults相当于是默认的数据值,当进行创建实列时,进行GET方法调用时,直接使用的是默认的数据值。

    关于在BACKBONE中对象如何实现继承,我们直接看下代码:

    1 var  M =   Backbone.Model.extend({
    2             aaa: function(){
    3                 console.log('婷风');
    4             }
    5       });
    6      var  childM =    M.extend(); //继承父类的模型                 
    7      var  model = new  childM;  //声称一个实列的对象
    8      model.aaa();

    控制台打印结果为:

    关于自定义事件

    BACKBONE有很多事件,比如on事件,这里了举个栗子。具体的可看官网给的列子。

    object.on(event, callback, [context])

    在 object 上绑定一个callback回调函数。 只要event触发,该回调函数就会调用。

     1 var  M = Backbone.Model.extend({
     2              defaults : {
     3                   name : '婷风'
     4              },
     5              initialize : function(){
     6                   this.on('change',function(){
     7                      console.log(123);
     8                   });
     9              }
    10     });
    11 
    12     var  model = new M;
    13     model.set('name' , 'lkm');

    这里给初始的default改变了其name属性,所以会触发change事件,从而发生相对应的行为。

    打印结果如下:

    上面那个是不管什么属性发生改变都会触发该事件,下面来看下特定的事件触发。

     1 var  M = Backbone.Model.extend({
     2              defaults : {
     3                   name : '婷风'
     4              },
     5              initialize : function(){
     6                   this.on('change : name',function(){   //这里指定了只当name属性发生改变时才会触发该事件
     7                      console.log(123);
     8                   });
     9              }
    10     });
    11     var  model = new M;
    12     model.set('name' , 'lkm');

    下面来看下回调函数里面带参数的,看下代码

     1 var  M = Backbone.Model.extend({
     2                 defaults : {
     3                          name : '婷风'
     4                 },
     5                 initialize : function(){
     6                          this.on('change : name',function(model){
     7                                   console.log(model);
     8                          });
     9                 }
    10      });
    11      var  model = new M;
    12      model.set('name' , 'lkm');

    我们看下打印台打印出来的东西:

    打印出来的都是model里面的一些属性。可自行贴码测试。

    如何将模型和试图联系起来?

    当然,肯定是MODEL和view想结合,举个列子看看。

     1 $(function(){
     2           var  M = Backbone.Model.extend({
     3                    defaults : {
     4                           name : '婷风'
     5                    }
     6           }) ;
     7           //创建一个试图,listenTo比on多一个参数,改写了this指向
     8           var  V = Backbone.View.extend({
     9                    initialize : function (){
    10                       this.listenTo(this.model , ' change' , this.show); //操作的元素 |数据发生改变的时候,发生show事件
    11                    },
    12                    show : function (model){
    13                        $('body').append('<div>' + model.get('name') + '</div>');
    14                    }
    15            });
    16            var   m = new  M; 
    17            var    v  = new  V({model:m});
    18            m.set('name' , 'jt' );
    19    });
    View Code

    打印出来的结果如下:该DIV渲染到body中

    关于数据与服务器

    Backbone.sync 是 Backbone 每次向服务器读取或保存模型时都要调用执行的函数。 默认情况下,它使用 jQuery.ajax 方法发送 RESTful json 请求,并且返回一个 jqxhr。 如果想采用不同的持久化方案,比如 WebSockets, XML, 或 Local Storage,我们可以重载该函数。

    Backbone.sync 的语法为 sync(method, model, [options])

    默认 sync 映射 REST 风格的 CRUD 类似下面这样:

    • create → POST   /collection
    • read → GET   /collection[/id]
    • update → PUT   /collection/id
    • patch → PATCH   /collection/id
    • delete → DELETE   /collection/id 

    来看下列子:

     1 Backbone.sync = function(method , model){   //AJAX请求
     2            cnsole.log(method + ":" + JSON.stringify(method));
     3     }
     4 
     5        var  M =  Backbone.Model.extend({
     6             defaults : {
     7                     name : '婷风'
     8             },
     9                      url : '/user'  //后台的地址
    10              }) ;
    11          var  m = new  M;
    12           m.save(); //将数据保存到服务器上
    13           m.save({name : 'jt'});//更新操作

    我们看下控制台效果:

    再来看下如何更新数据库里面的数据:

     1 Backbone.sync = function(method , model){   //AJAX请求
     2           console.log(method + ":" + JSON.stringify(method));
     3    }
     4   var C = Backbone.Collection.extend({ //集合绑定事件
     5                   initialize : function(){
     6                        this.on('reset', function(){  //当服务器数据获取成功,调用该事件
     7                                            console.log('jt');
     8                         })
     9                   },
    10                  url : '/users'
    11     });
    12     var  models = new C;
    13     models.fetch();//从服务器上进行数据的更新

    看下控制台打印效果:

    其实原理和我们平常请求数据的增删改查是一样的,后端给API,前端根据字段发送AJAX请求,获取数据等。

    关于路由和历史管理

    通过 Backbone.Router.extend 来创建路由模型,链接到不同的指定的动作和事件.当应用已经全部链接到路由时,需利用Backbone.history.start() 或者Backbone.history.start({pushState: true}) 来确保驱动初始化 URL 的路由。

    我们来具体的看个列子:

     1 //路由与历史管理                 
     2   var   Workplace  =  Backbone.Router.extend({
     3         routes: {
     4                 "help" : "help" ,  //对应的调用方法  #help
     5                  "search/:query" : "search" ,      #search/help
     6                  "search/:query/p:page" : "search"  #search/query/p3
     7         } ,
     8 
     9          help : function(){
    10                    console.log('111');
    11                      //alert('111');
    12           },
    13 
    14          search : function(query , page){
    15                      console.log('222');
    16                      //alert('333');
    17           }
    18   });
    19   var  w = new    Workplace ;  
    20   Backbone.history.start(); //保证路由在浏览器中有历史管理
    View Code

    开始创建一个自定义的路由类。当匹配了 URL 片段便执行定义的动作,并可以通过routes 定义路由动作键值对。 注意:要避免在路由定义时使用前导斜杠!!!!!

    关于事件委托

     什么叫事件委托呢?即事件代理,利用冒泡原理,将某一元素的事件,委托给其它元素处理的事件。

        好处:提高性能  |  新添加的元素,依然保留了该事件。

     1 //事件委托
     2  $(function(){          
     3       var   V  =  Backbone.View.extend({
     4             el : $('body'),   //el当前的委托人。用BODY作为委托人
     5             events : {        //事件
     6                   'click  input' : 'aaa' ,
     7                   'mouseover li ' : 'bbb'
     8             },
     9             aaa : function(){
    10                    console.log('aa');
    11             },
    12             bbb : function(){
    13                    console.log('bb')
    14             }
    15        });
    16 
    17        var    view  = new  V;
    18 });
    View Code

     看下html相对应的代码:

    1 <input type="button" value="name">
    2 <ul>
    3      <li>11111111</li>
    4      <li>22222222</li>
    5      <li>33333333</li>
    6      <li>44444444</li>
    7 </ul>

    当点击Input时候,发生click事件,触发aaa,当鼠标移入li上时,触发bbb。

    关于前端模板

    好处:更好的实现mvc机制,让js的操作与试图进行分离。通常是template:_.template($('#template').html())这种写法。

     1 //前端模板 :更好的让js的操作与视图进行分离   
     2    $(function(){
     3           var  M = Backbone.Model.extend({
     4                defaults : {
     5                      name : '婷风'
     6                }
     7           }) ;
     8      //创建一个试图,listenTo比on多一个参数,改写了this指向
     9           var  V = Backbone.View.extend({
    10                initialize : function (){
    11                      this.listenTo(this.model , ' change' , this.show); //操作的元素 | 数据发生改变的时候,发生show事件
    12                 },
    13                 show : function (model){
    14                      $('body').append(this.template(this.model.toJSON()  )); //调用模板的方法
    15                 },
    16                 template : _.template($(' #template').html()) 
    17            });
    18            var   m  = new  M; 
    19            var   v  = new  V({model:m});
    20            m.set('name' , 'jt' );
    21      });
    View Code

     html代码如下:

    <div  id="template"></div>

    实例演练分析

    效果地址:http://www.css88.com/doc/backbone/examples/todos/index.html

      下载地址:https://github.com/foreverjiangting/backbone/tree/master/examples/todos

      主页html代码如下:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4   <meta charset="utf-8">
     5   <title>Backbone.js Todos</title>
     6   <link rel="stylesheet" href="todos.css"/>
     7   <script type="text/javascript" src="jquery.js"></script>
     8   <script type="text/javascript" src="underscore-min.js"></script>
     9   <script type="text/javascript" src="backbone.js"></script>
    10   <script src="backbone.localStorage.js"></script>
    11   <script src="todos.js"></script>
    12 
    13 </head>
    14 <body>
    15   <div id="todoapp">
    16     <header>
    17       <h1>Todos</h1>
    18       <input id="new-todo" type="text" placeholder="What needs to be done?">
    19     </header>
    20 
    21     <section id="main">
    22       <input id="toggle-all" type="checkbox">
    23       <label for="toggle-all">Mark all as complete</label>
    24       <ul id="todo-list"></ul>   //包含每个li元素
    25     </section>
    26 
    27     <footer>
    28       <a id="clear-completed">Clear completed</a>
    29       <div id="todo-count"></div>
    30     </footer>
    31 
    32   </div>
    33 
    34   <div id="instructions">
    35     Double-click to edit a todo.
    36   </div>
    37 
    38   <!-- 单个li的Templates -->
    39 
    40   <script type="text/template" id="item-template">
    41     <div class="view">
    42       <input class="toggle" type="checkbox" <%= done ? 'checked="checked"' : '' %> />
    43       <label><%- title %></label>
    44       <a class="destroy"></a>
    45     </div>
    46     <input class="edit" type="text" value="<%- title %>" />   //双击li中的输入框进行编辑
    47   </script>
    48 
    49 
    50 <!-- 底部的Templates -->
    51   <script type="text/template" id="stats-template">
    52     <% if (done) { %>
    53       <a id="clear-completed">Clear <%= done %> completed <%= done == 1 ? 'item' : 'items' %></a>
    54     <% } %>
    55     <div class="todo-count"><b><%= remaining %></b> <%= remaining == 1 ? 'item' : 'items' %> left</div>
    56   </script>
    57 
    58   </body>
    59 </html>
    View Code

    -----------------------------------------------------------------------------------------------------------------

    so,any什么。。。 。。。

    作者:婷风

    出处:http://www.cnblogs.com/jtjds/p/5867193.html

  • 相关阅读:
    LESS的简单介绍
    实例化对象的过程
    原生的AJAX
    http基础
    display的属性值测试
    js中arguments的简单用法
    JS数组控制台排序
    js中使用switch的语法结构和意义
    js入门—控制台输出console.log
    css入门—position详解
  • 原文地址:https://www.cnblogs.com/wangyongsong/p/8134151.html
Copyright © 2011-2022 走看看