backbone 要點知識整理

1.backbone 是個mvc的庫,官方文檔說它是個庫,而不是個框架。庫和框架的區別就是,庫只是個工具,方便你的項目應用,不會改變你的項目結構,而框架會有一套本身的機制,項目須要遵循框架的設計來實現,你要適應框架。backbone 能夠看成庫或者框架來用均可以。看成庫,你能夠只使用它的部分特性,如事件;看成框架的話,可使用它的完整的mvc,router,history。javascript

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
css

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的部分方法,方便操做html

6.事件:
a.若是你的一個頁面含有大量的不一樣事件,咱們約定使用冒號來爲事件添加 命名空間 俗成地使用冒號來命名:"poll:start", 或 "change:selection"java

//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);jquery

結束監聽事件
view.stopListening(model);ajax

c.change:[attribute]" (model, value, options) — 當一個model(模型)的某個特定屬性被更新時觸發chrome

"change:[命名空間]" 和 change:[attribute] 的區別:
"change:[命名空間]" 只是"事件:[命名空間]"的一個特例,既能夠是change事件,也能夠是其它事件,包括自定義事件。須要手動觸發。
change:[attribute] 它會關聯model的屬性,當一個model(模型)的某個特定屬性被更新時觸發json

//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.api

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
相關文章
相關標籤/搜索