zoukankan      html  css  js  c++  java
  • backbone 要点知识整理

    1.backbone 是个mvc的库,官方文档说它是个库,而不是个框架。库和框架的区别就是,库只是个工具,方便你的项目应用,不会改变你的项目结构,而框架会有一套自己的机制,项目需要遵循框架的设计来实现,你要适应框架。backbone 可以当作库或者框架来用都可以。当作库,你可以只使用它的部分特性,如事件;当作框架的话,可以使用它的完整的mvc,router,history。

    2.backbone的优点:a.实现了mvc结构,虽然controller里面只有router。b.可以通过事件监听,自动刷新view
    backbone的缺点:a.所有的业务逻辑都在view里,view太重;b.锚点路由不利于seo
    3.backbone的model,通过Backbone.sync来代理和服务器交互。也可以重写方法,把数据放到其它地方。
    4.collection 也使用Backbone.sync 将一个集合状态持久化到服务器。
    重写Backbone.sync 来完成自定义处理;参考ackbone.localStorage.js

    Backbone.sync=function(method,model){
    alert(""+method+":"+model.url);
    }
    var list=new Backbone.Collection();
    list.url="/search";
    list.fetch();
    collection的fetch方法 例子

    可以监听集合chang事件,集合中模型发生变化都会出发change事件
    5.model和collection 都集成了undercore的部分方法,方便操作

    6.事件:
    a.如果你的一个页面含有大量的不同事件,我们约定使用冒号来为事件添加 命名空间 俗成地使用冒号来命名:"poll:start", 或 "change:selection"

    //sample1
    var obj={};
    _.extend(obj,Backbone.Events);
    obj.on("myEvt:first",function(e){
    alert("hi,and data is "+e.data);
    });
    obj.on("myEvt:second",function(e){
    alert("hi,and data is "+e.data);
    });
    obj.trigger("myEvt:first",{data:"first"});
    obj.trigger("myEvt:second",{data:"second"});
    事件命名空间例子
    //sample2
    var obj={};
    _.extend(obj,Backbone.Events);
    obj.on("all",function(e,data){
    console.log("hi,and data is "+data);
    });
    obj.trigger("myEvt:first","first");
    obj.trigger("myEvt:second","second");
    obj.trigger("test","test");
    绑定all事件

    b.让 object 监听 另一个(other)对象上的一个特定事件。object.listenTo(other, event, callback)
    而使用这种形式的优点是:listenTo允许 object来跟踪这个特定事件,并且以后可以一次性全部移除它们。
    callback 在object上下文中执行
    view.listenTo(model, 'change', view.render);

    结束监听事件
    view.stopListening(model);

    c.change:[attribute]" (model, value, options) — 当一个model(模型)的某个特定属性被更新时触发

    "change:[命名空间]" 和 change:[attribute] 的区别:
    "change:[命名空间]" 只是"事件:[命名空间]"的一个特例,既可以是change事件,也可以是其它事件,包括自定义事件。需要手动触发。
    change:[attribute] 它会关联model的属性,当一个model(模型)的某个特定属性被更新时触发

    //change:[attribute] sample:
    var model=new Backbone.Model({title:'天猫',name:'商城'});
    model.on('change:title',function(e){
    // console.log('title changed',JSON.stringify(e));
    alert('title changed:'+JSON.stringify(e));
    })    
    model.set({title:'京东'});
    //change:[命名空间] sample:
    var obj={};
    _.extend(obj,Backbone.Events);
    obj.on("myEvt:first",function(e){
    alert("hi,and data is "+e.data);
    });
    obj.on("myEvt:second",function(e){
    alert("hi,and data is "+e.data);
    });
    obj.trigger("myEvt:first",{data:"first"});
    obj.trigger("myEvt:second",{data:"second"});

     7.

    Backbone.sync 是backbone数据持久化的函数接口,用于读取和保存数据。默认情况下,它使用 jQuery.ajax 方法发送 RESTful json 请求,并且返回一个 jqXHR。 如果想采用不同的持久化方案,比如 WebSockets, XML, 或 Local Storage,我们可以重载该函数。
    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

    model.fetch/model.save/model.destory 会通过Backbone.sync操作持久化的数据

    collection.fetch/collection.create 会通过Backbone.sync操作持久化的数据

    //sample
    Backbone.sync = function(method, model) {
      alert(method + ": " + JSON.stringify(model));
      model.set('id', 1);
    };
    var book = new Backbone.Model({
      title: "The Rough Riders",
      author: "Theodore Roosevelt"
    });
    
    book.save();//create: {"title":"The Rough Riders","author":"Theodore Roosevelt"}
    book.save({author: "Teddy"});//update: {"title":"The Rough Riders","author":"Teddy","id":1}

    8.todo sample 分析

    a.默认情况下,添加一个新的记录,会先触发model add event, 然后才会触发Backbone.sync的方法。

    input new item and click enter -> collection.create->trigger collection add event -> Backbone.sync ('create')->new Store() ('create') -> localStorage.setItem()

    b.可以通过设置,{wait: true} ,  先触发Backbone.sync方法,然后在触发model add event.  例如:app.list.create(this.newAttributes(),{wait: true});

     todo sample完整代码

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
            <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1">
            <style type="text/css">
        #todoapp ul {
          list-style-type: none;         
           list-style-type: none; /* Hides bullet points from todo list */
          }              
         #todo-list input.edit {
           display: none; /* Hides input box*/
         }
         #todo-list .editing label {
           display: none; /* Hides label text when .editing*/
         }    
         #todo-list .editing input.edit {
           display: inline; /* Shows input text box when .editing*/
         }    
            </style>
        </head>
        <body>
    
    
            <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
            <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.3/underscore-min.js"></script>
            <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"></script>
            <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/backbone-localstorage.js/1.0/backbone.localStorage-min.js"></script>
    
            <!-- <script type="text/javascript" src="backbone-localstorage.js"></script> -->
    
        <section id="todoapp">
         <header id="header">
           <h1>Todos</h1>
          <input id="new-todo" placeholder="What needs to be done?" autofocus>
          <div>
             <a href="#/">show all</a> |
             <a href="#/pending">show pending</a> |
             <a href="#/completed">show completed</a>
          </div> 
         </header>
         <section id="main">
           <ul id="todo-list"></ul>
         </section>
       </section>
    
      <!-- Templates -->
      <script type="text/template" id="item-template">
        <div class="view">
          <input class="toggle" type="checkbox" <%= completed?'checked':'' %> />
          <label><%= title %></label>
          <input class="edit" value="<%- title %>">
          <button class="destroy">remove</button>
        </div>
      </script>  
    
            <script type="text/javascript">
            var app={};
            app.myModel=Backbone.Model.extend({
                default:{
                    title:"",
                    completed:false
                },
                 toggle: function(){
                 this.save({ completed: !this.get('completed')});
                }                
            });
            app.modelList=Backbone.Collection.extend({
                model:app.myModel,
                localStorage:new Store("backbone-todo"),
                 completed: function() {
                     return this.filter(function( todo ) {
                       return todo.get('completed');
                     });
               },
               remaining: function() {
                 return this.without.apply( this, this.completed() );
               }      
            });
            app.list=new app.modelList();
    
            app.liview=Backbone.View.extend({
                tagName:"li",
                tpl:_.template($("#item-template").html()),
                render:function(){
                    this.$el.html(this.tpl(this.model.toJSON()));
                    this.input=$(".edit");
                    return this;
                },
                initialize: function(){
                     this.model.on('change', this.render, this);
                    this.model.on('destroy', this.remove, this); 
                   },      
               events: {
                 'click label' : 'edit',
                 'keypress .edit' : 'updateOnEnter',
                 'blur .edit' : 'close',
                 'click .toggle': 'toggleCompleted',
                  'click .destroy': 'destroy'
               },
               edit: function(){
                 this.$el.addClass('editing');
                 this.input.focus();
               },
               close: function(){
                 var value = this.input.val().trim();
                 if(value) {
                   this.model.save({title: value});
                 }
                 this.$el.removeClass('editing');
               },
                toggleCompleted: function(){
                    this.model.toggle();
                },
               updateOnEnter: function(e){
                 if(e.which == 13){
                   this.close();
                 }
               },
               destroy:function(){
                   this.model.destroy();
               } 
            })
    
            app.view=Backbone.View.extend({
                el:"#todoapp",
                initialize:function(){
                    this.input=$("#new-todo");
                    app.list.on("add",this.addAll,this);
                    app.list.on("reset",this.addAll,this);
                    app.list.fetch();//拉取数据
                },
                addAll:function(){
                    $("#todo-list").html('');
                    app.list.each(this.addOne,this);
                },
                addOne:function(md){
                    var li=new app.liview({model:md});
                    $("#todo-list").append(li.render().el);
                },
                events: {
                     'keypress #new-todo': 'createTodoOnEnter'
                },
                createTodoOnEnter:function(e){
                   if ( e.which !== 13 || !this.input.val().trim() ) { 
                      return;
                    }
                    app.list.create(this.newAttributes(),{wait: true});//,{wait: true}
                    this.input.val(''); // clean input box
                },
                  newAttributes: function(){
                    return {
                      title: this.input.val().trim(),
                      completed: false
                    }
                }
            });
    
         app.myRouter=Backbone.Router.extend({
             routes:{
                 "":"index",
                 "search":"search",
                 "search/:id":"search"
             },
             index:function(){
                 console.log("this is home page.");
                 Backbone.history.stop();
             },
             search:function(id){
                 console.log("this is search page. And param is "+id);
             }
         });  
         app.router=new app.myRouter();
        
         var helloView=new app.view();
          Backbone.history.start();    
            </script>
        </body>
    </html>
    todo sample
                //1.collection.add(model)
                //collection.add -> collection.set -> model.trigger("add") -> triggerEvents -> (ev = events[i]).callback.call(ev.ctx, a1, a2, a3)
    
    
                //2.listenTo
                //A.listenTo(B,'click',callback) -> B.on('click',callback,A);
    View Code
  • 相关阅读:
    钩子函数和回调函数的区别
    观察者模式(Observer)和发布-订阅者模式(Publish/Subscribe)区别
    前端解决跨域问题的终极武器——Nginx反向代理
    CORS(cross-origin-resource-sharing)跨源资源共享
    Vue父子组件通讯
    js的变量——基本类型保存在栈中,引用类型保存在堆中
    python
    CentOS7 下 Zabbix3.4 源码安装
    linux配置ssh公钥认证,打通root用户的免密码输入的scp通道
    python
  • 原文地址:https://www.cnblogs.com/bg57/p/8320374.html
Copyright © 2011-2022 走看看