`
zhouyrt
  • 浏览: 1173410 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Backbone事件模块

 
阅读更多

事件模块Backbone.Events是Backbone的核心,Model、Collection、View都依赖它。

此外,事件模块的所有方法都挂在了全局的Backbone上,如果你的代码中需要用到自定义事件(实现观察者模式),可以直接使用它。

 

标示符Events是内部的一个引用,为讨论方便,这里也省去了前缀Backbone,这篇文章会从以下几个点分析

  • Events API
  • Events的用法
  • Events内部数据结构 (_events/_listeners)
  • 特殊事件: “all”
  • Events与Model、Collection、View、Router、History的关系

 

一、Events API

1.0之前只提供了三个基本方法 on/once/off/trigger,1.0开始增加了几个实用方法 listenTo/listenToOnce/stopListening。


 

以下是各个方法的意义

  • on 添加自定义事件
  • off 删除自定义事件
  • trigger 派发自定义事件
  • once 添加只执行一次的自定义事件 (内部依赖于_.once)
  • listenTo 添加一个观察对象
  • listenToOnce 添加一个仅执行一次的观察对象
  • stopListening 删除添加的观察对象

二、Events的代码鸟瞰

var Events = Backbone.Events = {
    on: function(name, callback, context) {
        // ...
    },
    once: function(name, callback, context) {
        // ...
    },
    off: function(name, callback, context) {
        // ...
    },
    trigger: function(name) {
        // ...
    },
    stopListening: function(obj, name, callback) {
        // ...
    }
};
 
var eventSplitter = /\s+/;
var eventsApi = function(obj, action, name, rest) {
    // ...
};
var triggerEvents = function(events, args) {
    // ...
};
var listenMethods = {listenTo: 'on', listenToOnce: 'once'};
 
_.each(listenMethods, function(implementation, method) {
    Events[method] = function(obj, name, callback) {
        // ...
    };
});
 
Events.bind   = Events.on;
Events.unbind = Events.off;
 
_.extend(Backbone, Events);

1. 先定义了一个对象(单例),直接挂上了接口方法on/once/off/trigger/stopListening,注意虽然Events头字母大写,这里不是定义一个类或构造器,而是一个单例对象

    剩下的变量和函数都是辅助这个对象的,它们都在闭包空间里,外部不可访问如eventSplitter、eventsApi等

2. eventSplitter用来实现空格间隔一次添加多个事件,如 .on('event1 event2', handler)

3. eventsApi实现的很巧妙,它辅助on/once、off、trigger完成事件的添加、删除、派发。你会发现这里是一个递归调用,来实现一些批量添加事件。如

// 空格间隔批量添加多个事件
.on('event1 event2', handler)
 
// 哈希对象批量添加
var obj = {
    event1: handler1,
    event2: handler2,
    event3: handler3
}
.on(obj)

4. triggerEvent辅助trigger方法实现派发事件,它的实现有些特殊,见 冗余换性能

5. 后面的listenMethod和一个each迭代,会给Events添加两个新方法listenTo和listenToOnce

6. 再下面两行给on/off分别取了别名bind/unbind。其实这也是为了兼容老版本,最早的版本添加/删除事件为bind/unbind。

7. 最后一行把Events掺合到全局的Backbone对象上了

拓扑图如下



 

三、Events内部数据结构 (_events/_listeners)

相对来说,目前的内部数据结构比较简单。采用传统的先哈希,后数组存储事件处理器对象,处理器对象上有callback和context及ctx。其内部有两个关键对象_eventshe _listeners,都以下划线开头,说明这是私有的(并非真正私有,一种语法约定,真正私有可使用闭包实现),仅供内部使用。

_events 这个哈希是默认是挂在Backbone.Events上,由于Events是一个对象,所以很容易被Mix到任何想增加自定义事件的类或对象上。此时_events则挂在该对象上。如Backbone.Model,Backbone.Collection,Backbone.View,当给其实例添加自定义事件时,_events则挂在它们的实例对象上。

 

_events的结构如下




_.extend(Backbone, Events);

_listeners 和 _events一样默认也是挂在Backbone.Events上。顾名思义,它是一个监听器,即可以为其它对象(具有Backbone.Events的所有方法的对象)被添加事件。它的key是以字母“l”开头后跟递增的数字组成,value是一个 “a mixin of Backbone.Events”。

 

_listeners的结构如下




最后又把Events上的所有方法都拷贝到标示符Backbone这个全局对象上,即给Backbone添加了如下方法。这时可以很方便的使用它给自己的类添加自定义事件。



 

 

四、 特殊事件“all”

事件名“all”,在trigger方法中,仔细看代码,你会发现trigger方法中调用了两次triggerEvents,一次是通过参数传进来的事件,另一次则固定为“all”事件。

var events = this._events[name];
var allEvents = this._events.all;
if (events) triggerEvents(events, args);
if (allEvents) triggerEvents(allEvents, arguments);

trigger的通常实现只需把事件名,参数传进来,取哈希(这里是_events)上取该事件的所有handlers(存在在数组里),挨个执行。但这里为什么每一次trigger调用还要单独取下all事件,然后执行呢?

如果只看Backbone.Events模块,是很难理解的。那么就搜索下整个Backbone.js,看“all”事件在哪些地方使用到。最后发现只在Backbone.Collection中用到,且仅一处。

model.on('all', this._onModelEvent, this);

只看这一行代码,还是难以理解。需要结合Backbone.Model和Backbone.Collection一起看。

这里先简单说下,我们知道这行代码所在方法是Collection.add,在往collection中添加model时执行的,即添加的model都会注册一个“all”事件。而当model自身销毁(destroy)或修改(change)的时候,需要通知其所在Collection。

 

例如,model销毁后,Collection需要在集合中把它删除,Collection的长度也需要减一。model修改后,也需要通知Collection,这样给Collection添加的change事件也会触发。

这就是“all”事件的真正用途,以前曾想既然Backbone的View和通信都依赖于jQuery,那么事件模块也完全可以使用$.Callbacks。不曾想到还有一个特殊的“all”事件。

 

五、Events与Model、Collection、View、Router、History的关系

来看下代码

_.extend(Model.prototype, Events, {
 
})
_.extend(Collection.prototype, Events, {
 
})
_.extend(View.prototype, Events, {
 
})
_.extend(Router.prototype, Events, {
 
})

 

把事件模块mixin到这几个类的原型上去了。一句话,这些类都具有Pub/Sub的功能,即都可以实现自定义事件,它们之间也就可以通过事件很方便的降低耦合。如果在加上数据、视图、逻辑的分层效果,这就是整个Backbone的精华了。

 

相关:

冗余换性能-从Backbone的triggerEvents说开了去

 

 

  • 大小: 36.7 KB
  • 大小: 39.5 KB
  • 大小: 39.5 KB
  • 大小: 34.8 KB
  • 大小: 34.2 KB
分享到:
评论

相关推荐

    slider-widget:带有Backbone事件模块的jQuery UI小部件

    使用Backbone,我们将事件绑定到我们的对象,侦听对活动数据点的更改,然后在slider.on()实例中触发事件。 slider.on('change', function() {// your custom event});更新并拆除滑块,而无需刷新页面。 slider....

    Backbone.js的事件绑定

    通过熟练掌握Backbone.js的事件绑定机制,开发者能够构建出响应式、易于维护的应用程序,同时保持代码的整洁和模块化。在学习过程中,参考提供的源代码,结合实践,可以更好地理解和应用这些概念。

    backbone整合require例子

    **标题解析:** "backbone整合require例子" 这个标题表明我们将讨论如何将Backbone.js框架与RequireJS模块加载器结合使用。Backbone.js是一个轻量级的JavaScript库,用于构建可维护的前端应用程序,而RequireJS则是...

    第P9周:YOLOv5-Backbone模块实现

    第P9周:YOLOv5-Backbone模块实现

    require+backbone结合开发的例子

    在JavaScript的世界里,Backbone.js是一个著名的轻量级MVC(模型-视图-控制器)框架,它提供了数据模型、视图以及事件处理等概念,帮助开发者构建结构化的Web应用。"require+backbone结合开发的例子"这个主题,指的...

    Backbone.js(1.1.2) API中文文档.zip Backbone.js离线文档

    Backbone.js是一款轻量级的JavaScript库,专为构建丰富的Web应用程序而设计。它通过提供模型(Models)、视图(Views)、集合...通过深入理解和实践,你可以利用Backbone.js构建出高效、模块化的Web应用程序。

    BACKBONE.JS应用程序开发

    , 《backbone.js应用程序开发》先从了解mvc、spa和backbone的基本知识开始,然后着手构建示例应用程序——一个简单的todo列表应用程序、restful风格的图书应用程序、以及使用backbone和requirejs的模块化应用程序。...

    实例讲解JavaScript的Backbone.js框架中的View视图

    在上述过程中,Backbone.js不仅简化了DOM操作,还通过事件驱动的方式使视图与数据模型解耦,使得应用更加模块化,更易于维护和扩展。Backbone.js的View视图是单页面应用开发中不可或缺的一部分,它通过模板、事件...

    backbone 入门指南

    ### Backbone.js入门指南知识点概述 #### 一、为什么需要Backbone.js?...以上内容涵盖了Backbone.js的基础知识和进阶技巧,以及如何使用Require.js来模块化组织Backbone应用程序。希望这些信息对你有所帮助。

    backbone_js_1.1.2

    Backbone.js是一款轻量级的...它强调代码的模块化和数据驱动,使得开发者可以更专注于业务逻辑,而非底层实现细节。通过合理地利用Backbone.js的核心组件,开发者能够构建出具有高度互动性和响应性的Web应用。

    backbone实例demo

    Backbone.js是一个轻量级的JavaScript库,专为构建可维护和模块化的Web应用程序而设计。它提供了一组数据模型(Model)、视图(View)和路由器(Router)的结构,帮助开发者组织代码并实现MVC(Model-View-...

    Backbone.js应用程序开发

    , 《backbone.js应用程序开发》先从了解mvc、spa和backbone的基本知识开始,然后着手构建示例应用程序——一个简单的todo列表应用程序、restful风格的图书应用程序、以及使用backbone和requirejs的模块化应用程序。...

    用Backbone.js写的小项目

    8. **模块化和组织结构**: 为了保持代码的清晰和可维护性,Backbone.js项目通常会采用模块化的方式组织代码,每个模块对应一个单独的JavaScript文件,比如Model、View、Router等。这样的组织结构使得代码更容易理解...

    backbone_api_frame

    在Backbone_API_frame中,Backbone.js被用来构建可复用、可维护的组件,通过事件驱动的模式,使得代码更加模块化,降低了组件间的耦合度。 **ExtJS** ExtJS是一个完整的JavaScript UI框架,提供了丰富的组件库,...

    backbone文档

    总的来说,Backbone.js通过提供一套MVC结构,使得前端开发更加模块化和有序。开发者可以利用它构建可扩展、可维护的复杂前端应用,同时享受到JavaScript社区提供的各种插件和工具的便利。随着前端开发需求的增长,...

    Backbone.Marionette.pdf

    Marionette作为Backbone的一个高级模块化架构,它提供了一系列工具和模式来组织代码,使大型应用的管理变得更为简单。本书首先介绍了如何设置项目环境,包括资产组织、获取所需资源以及显示静态视图。随后,书中深入...

    Backbone.js开发秘笈源码

    Backbone.js使用事件系统连接视图和模型,当模型改变时,可以触发视图的更新,反之亦然。通过`listenTo`和`stopListening`方法,视图可以订阅和取消订阅模型或集合的事件。 现在,让我们转向"Backbone.js开发秘笈...

    backbone实现的一个小demo

    Backbone.js是一个轻量级的JavaScript库,它为构建复杂的Web应用提供了模型-视图-控制器(MVC...通过这个项目,开发者可以了解如何使用Backbone与其他库协同工作,以及如何组织代码以构建一个响应式、模块化的Web应用。

    前端项目-backbone.radio.zip

    它提供了一个全局的事件通道,用于应用中的模块间通信,解决了传统事件系统可能导致的命名冲突和难以跟踪的问题。 3. **消息传递模式**:在Backbone.Radio中,消息传递模式通过`Radio.channel`来实现。开发者可以...

Global site tag (gtag.js) - Google Analytics