201507271337_《Backbone之三——Event、Controller(Router)、View、Collection、Model》

一. Event

新建了一个对象,再与事件混合后,对象就可以用事件方法了。

例如:

1 var obj = {};       //js对象

2 _.extend(obj, Backbone.Events);     //把Backbone.Events扩展到obj对象中。这时这个对象就拥有操作事件的方法了。_是underscore.js的对象,相当于jquery.js中的$

3 

4 obj.bind('data', function(data) { 

5   console.log('Receive Data: ' + data); 

6  }); 

7 obj.trigger('data', 'I/'m an Backbone.event');      //打印Receive Data: I'm an Backbone.event

8 obj.unbind('data'); 

9 obj.trigger('data', 'I/'m an Backbone.event'); 

另外,如果事件很多,可以给事件加上命名空间,例如"change:selection"。属性事件会先于正常事件触发。比如:

我们先监听了change事件,然后再监听了change:name属性事件,但change事件(改变name的值)在触发时,总是会先触发属性事件,然后再触发change事件。如果改变的不是name的值而是其他的值,这里只会触发change事件,而不会触发change:name属性事件。

 

二. Route(Controller)

 

var controller = Backbone.Controller.extend({ 
     routes: { 
         "": "home", 
         "!/comments": "comments", 
         "!/mentions": "mentions", 
         "!/:uid": "profile", 
         "!/:uid/following": "following", 
         "!/:uid/followers": "followers", 
         "!/:uid/status/:id": "status", 
         "!/search/users/:query": "user_search", 
         "!/search/:query": "search" 
     }, 
  initialize: function(){...}  ,
     home: function(){...} ,
     comments: function() {...} ,
     mentions: function() {...} ,
     profile: function(a) {...} ,
     status: function(a, b) {...} ,
     following: function(a) {...} ,
     followers: function(a) {...} ,
     user_search: function(a) {...} ,
     search: function(a) {...} 
});

 

var custom = new controller();  

 

Backbone.history.start();

... ...

 

 

三. Route(Controller)

view有两个作用,监听事件显示数据

var view = Backbone.View.extend({ 
     model: User, //这个View的模型
     className: "components cross", 
     template: $("#user-info-template").html(), 
     initialize: function() {    //new view({})就会调用这个初始化方法
    _.bindAll(this, "render"); 
    this.model.bind("change", this.render)    //模型User绑定change事件
     }, 
     render: function() { 
    var a = this.model; 
    $(this.el).html(Mustache.to_html(this.template, a.toJSON()));    //使用了Mustache模板库,来解析模板,把模型User中的数据,转换成json,显示在模板中
           $(this.el).find(".days").html(function() {   //再进行细微的改变
               var b = a.get("created_at");     //取到模型User中的created_at的值
               return b;
    }); 
    return this ;
  } 
}); 


在initialize中,一旦User类(模型)触发了change事件就会执行render方法,继而显示新的视图。
render方法中总是有个约定俗称的写法的。this.el是一个DOM对象,render的目的就是把内容填到this.el中。this.el会根据view提供的tagName, className, id属性创建,如果一个都没有,就会创建一个空的DIV。
更新完this.el后,我们还应该return this;这样才能继续执行下面的链式调用(如果有的话)。
我们也可以用$(view.el).remove()或者view.remove()很方便的清空DOM。
View层有一个委托事件的机制。


var view = Backbone.View.extend({ 
     className: "likers-manager", 
  template: $("#likers-components-template").html(),   //模板HTML
  events: { 
         "click .btn-more": "loadMore"    
     }, 
  initialize: function() {    //new view({}),就会调用
           _.bindAll(this, "render", "updateTitle", "loadOne", "loadAll", "loadMore");   //调用underscore的bingAll方法
     },
  render: function() { ... } ,
  updateTitle: function() { ... } ,
     loadOne: function(a) { ... } ,
  loadAll: function() { ... } ,
     loadMore: function(a) { ... } 
}); 
在这里面有个events的键值对,格式为{"event selector": "callback"},其中click为事件,.btn-more是基于this.el为根的选择器,这样一旦约定好,当用户点击.btn-more的元素时,就会执行loadMore方法

 

 

四. Model

1. Model 用来创建数据,校验数据,存储数据到服务器端。Models还可以绑定事件。比如用户动作变化触发 model 的 change 事件,所有展示此model 数据的 views 都会接收到 这个 change 事件,进行重绘。
最简单的定义如下:

var Game = Backbone.Model.extend({});

稍微复杂一点:

var Game = Backbone.Model.extend({ 

  initialize: function(){ 

    

     }, 

  defaults: { 

             name: 'Default title', 

             releaseDate: 2011, 

  } 

});

 

initialize 相当于构造方法,初始化时调用(new时调用)
简单实用:

var portal = new Game({ name: "Portal 2", releaseDate: 2011}); 



var release = portal.get('releaseDate'); 



portal.set({ name: "Portal 2 by Valve"});

 

此时数据还都在内存中,需要执行save方法才会提交到服务器:

portal.save();

 

五. Collection

相当于Model的集合。需要注意的是,定义Collection的时候,一定要指定Model。 下面让我们为这个集合添加一个方法,如下:

var GamesCollection = Backbone.Collection.extend({ 

   model : Game, 

   old : function() { 

    return this.filter(function(game) { 

         return game.get('releaseDate') < 2009; 

     }); 

   } 

});

 

集合的使用方法如下:

var games = new GamesCollection 

games.get(0);

 

当然,也可以动态构成集合,如下:

  var GamesCollection = Backbone.Collection.extend({ 

   model : Game, 
   url: '/games' 

}); 

var games = new GamesCollection 
games.fetch();

 

 

这边的url告诉collection到哪去获取数据,fetch方法会发出一个异步请求到服务器,从而获取数据构成集合。(fetch实际上就是调用jquery的ajax方法)

模板解析是Underscore中提供的一个方法。且Underscore是Backbone必须依赖的库。
模板解析方法能允许我们在HTML结构中混合嵌入JS代码,就像在JSP页面中嵌入JAVA代码一样:

 <ul> 

  <% for(var i = 0; i < len; i++) { %> 

  <li><%=data[i].title%></li> 

  <% } %> 

</ul> 

 

通过模板解析,我们不需要在动态生成HTML结构时,使用拼接字符串的方法,更重要的是,我们可以将视图中的HTML结构独立管理(例如:不同的状态可能会显示不同的HTML结构,我们可以定义多个单独的模板文件,按需加载和渲染即可)。在Backbone中,你可以使用on或off方法绑定和移除自定义事件。在任何地方,你都可以使用trigger方法触发这些绑定的事件,所有绑定过该事件的方法都会被执行,如:

var model = new Backbone.Model(); 

model.on('custom', function(p1, p2) { 

     }); 



 model.on('custom', function(p1, p2) { 

    }); 

model.trigger('custom', 'value1', 'value2');   //将调用以上绑定的两个方法

model.off('custom'); 

model.trigger('custom');



// 触发custom事件,但不会执行任何函数,已经事件中的函数已经在上一步被移除  

 

 

通过重载Backbone.sync方法来适配现有的数据接口

 

你可能感兴趣的:(Collection)