Backbone.js系列教程五:Backbone.Events

Backbone.Events概述

Backbone.Events对象包含的方法有助于observer设计模式和一个调用pub/sub的可变observer模式。这些功能允许Backbone创建的不同类的对象(JavaScript对象)彼此解耦而相互通信。这是通过扩展(也就是_.extend(Model.prototype, Backbone.Events);)以下构造函数而完成的,所使用的函数都属于Backbone.Events

  • Backbone.Model()
  • Backbone.Collection()
  • Backbone.View()
  • Backbone.Router()
  • Backbone.History()

如果你还是无法理解observer设计模式,也不能理解pub/sub术语的概念,不如这样想,可以把Backbone.Events中的函数看做类似于 jQuery中的 $("").on(), $("").off(), $("").trigger(),  $("").one() 方法,它们的作用是为本机或自定义事件的DOM对象添加侦听事件。

Backbone.Events对象包含以下函数,功能是创建事件,触发事件,在基于事件的对象之间创建监听关系。

  • on(event, callback, context) 或 bind() 
  • off(event, callback, context) 或 unbind() 
  • trigger(event, arguments)
  • once(event, callback, context)
  • listenTo(other object, event, callback)
  • stopListening(other object, event, callback)
  • listenToOnce(other object, event, callback)

除了扩展上述的构造函数,Backbone命名空间对象本身也扩展(_.extend(Backbone, Backbone.Events);Backbone.Events属性,因此整个事件系统就是可用的。比如在下例中,我创建了一个通用的sayHi事件和一个eavesdropper对象,来监听Backbone对象上触发的任意sayHi事件。


  1. //对Backbone对象增加一个自定义事件
  2. Backbone.on("sayHi",
    function
    ()
    {
  3. console.log("Hi");
  4. });
  5.  
  6. //创建一个eavesdropper对象,用Backbone.Events继承对象
  7. var eavesdropper = _.extend({},
    Backbone.Events);
  8.  
  9. //令eavesdropper监听Backbone对象的自定义sayHi事件
  10. eavesdropper.listenTo(Backbone,
    "sayHi",
    function
    ()
    {
  11. console.log("I heard that");
  12. });
  13.  
  14. //触发/调用sayHi自定义事件
  15. Backbone.trigger("sayHi");
    //logs "Hi" and "I heard that"
  16.  
  17. /*记住Backbone通过事件来继承Backbone命名空间
  18. (i.e. cause Backbone did this: _.extend(Backbone, Backbone.Events);)*/

提示:

请注意,在上面我演示了Backbone对象中Backbone.Events的使用方式,但是Backbone.Events的初衷是继承前面提到的Backbone构造函数,并采用允许解耦通信的模型。

利用Backbone.Events继承任意对象

正如前面提到的,Backbone.Events对象和Backbone命名空间对象的属性也会被混进Backbone构造函数的继承原型链中。所以,利用Backbone.Events对象提供的功能可以继承任意对象。基本上Backbone.Events是一个独立的函数集,且能够与任意旧的JavaScript对象混合。下面我将证明这一点,首先继承A对象,然后验证Backbone.Events方法也带有A的属性。


  1. //利用Backbone.Events方法继承A对象
  2. var A = _.extend({name:"A"},
    Backbone.Events);
  3.  
  4. //验证A是否被Backbone.Events方法继承
  5. console.log(Object.keys(A));
  6.  
  7. /*上述日志:
  8.  
  9. ["name", "on", "once", "off", "trigger", "stopListening", "listenTo", "listenToOnce", "bind", "unbind"]
  10.  
  11. */

利用on()绑定事件对象

on()方法将绑定一个回调函数来调用一个事件触发对象。在以下代码中我绑定了一个whatsMyName事件到A对象,然后触发该事件。


  1. /利用Backbone.Events方法继承A对象
  2. var A = _.extend({name:"A"},
    Backbone.Events);
  3.  
  4. //当事件被触发时添加一个事件A让回调函数被调用
  5. A.on("whatsMyName",
    function
    ()
    {
  6. console.log(this.name);
    //this is A
  7. });
  8.  
  9. //在对象A触发whatsMyName事件,日志A
  10. A.trigger("whatsMyName");
  11.  
  12. /*参考通过on()的单一对象包含多个事件和回调的可能
  13. A.o{ callback1 : function(){}, callback2 : function() });
  14. */

提示:一个once(event,callback,context)方法的用法就类似于on()的用法,不同之处在于once(event,callback,context)的事件和回调函数在被第一次调用过后就被立即删除了,所以事件和回调仅发生一次。

利用on()绑定多个事件

on()接受一个字符串参数,可以包含用空格分隔的多个事件。下面我添加两个事件到A对象,它调用相同的函数,然后我使用两个不同的事件名触发回调。


  1. //利用Backbone.Events方法继承A对象
  2. var A = _.extend({name:"A"},
    Backbone.Events);
  3.  
  4. A.on("sayHi greet",
    function
    ()
    {
  5. console.log("Hello");
  6. });
  7.  
  8. //触发sayHi和greet, Hello会在控制台被打出两次
  9. A.trigger("sayHi");
  10. A.trigger("greet");

on()的命名空间事件

可以通过使用冒号在命名事件名称后加上空间名称。下面我添加了两个say事件和一个特殊的空间名称,用来调用使用这些名称间隔的事件。


  1. //利用Backbone.Events方法继承A对象
  2. var A = _.extend({name:"A"},
    Backbone.Events);
  3.  
  4. A.on("say:hi",
    function
    ()
    {
  5. console.log("Hi");
  6. });
  7.  
  8. A.on("say:hello",
    function
    ()
    {
  9. console.log("Hello");
  10. });
  11.  
  12. //触发say:hi和say:hello,注意我用同一个触发调用了两个事件
  13. A.trigger("say:hi say:hello");
  14.  
  15. //下面这样写不能同时触发两个事件
  16. A.trigger("say");

使用trigger()触发和传递值到一个回调函数

trigger()方法用来调用命名(即事件)的回调函数,在本小节中它被广泛的使用。传递给trigger()方法的第二个参数,是用于给回调函数提供传递值的。下面我在A触发回调函数,用于传递几个值。


  1. //利用Backbone.Events方法继承A对象
  2. var A = _.extend({name:"A"},
    Backbone.Events);
  3.  
  4. A.on("say",
    function
    (options)
    {
  5. console.log(options[0]);
  6. console.log(options[1]);
  7. });
  8.  
  9. //在A触发say事件,同一行中给回调函数传递了两个字符串
  10. A.trigger("say",
    ["Hello","Good Bye"]);

提示:

  1. 通过提供一个空格分隔的字符串作为trigger()列表里的第一个参数,就能同时触发你想调用的多个事件(也就是obj.trigger("event1 event2 event3");)。
  2. 当一个事件没有真正定义在某个对象上时,也可以被触发,任何监听这个事件的对象都会被通知这个事件已被触发。

利用on()来设置this,组织一个回调函数

传递给on()的第三个参数,作用是设置回调函数中的this文本。下面的代码中,我在A调用了一个回调,但是把回调文本中的this值设置为B


  1. //利用Backbone.Events方法继承A对象
  2. var A = _.extend({name:"A"},
    Backbone.Events);
  3. var B =
    {name:"B"};
  4.  
  5. //当事件A调用,设置回调文本(this)为B
  6. A.on("sayMyName",
    function
    ()
    {
  7. console.log(this.name);
  8. }, B);
  9.  
  10. //触发sayMyName
  11. A.trigger("sayMyName");
    //日志B,因为回调文本被修改了

 利用off()删除事件和回调函数

利用off()方法能够用于从一个对象删除单个事件、回调函数或全部事件,通常有以下五种用法。

1:删除已命名的回调函数


  1. //利用Backbone.Events方法继承A对象
  2. var A = _.extend({name:"A"},
    Backbone.Events);
  3.  
  4. var foo =
    function
    ()
    {
  5. console.log("foo");
  6. };
  7. var bar =
    function
    ()
    {
  8. console.log("bar");
  9. };
  10.  
  11. A.on("log",foo);
  12. A.on("log",bar);
  13.  
  14. A.trigger("log");
    //日志 后台输出foo以及bar
  15. A.off("log",foo);
    //删除foo回调
  16. A.trigger("log");
    //日志 后台只输出bar,因为foo被删除了 

2:删除对象的整个事件


  1. //利用Backbone.Events方法继承A对象
  2. var A = _.extend({name:"A"},
    Backbone.Events);
  3.  
  4. var foo =
    function
    ()
    {
  5. console.log("foo");
  6. };
  7. var bar =
    function
    ()
    {
  8. console.log("bar");
  9. };
  10.  
  11. A.on("log",foo);
  12. A.on("log",bar);
  13.  
  14. A.trigger("log");
    //日志 后台输出foo以及bar
  15. A.off("log");
    //删除log事件
  16. A.trigger("log");
    //日志无,因为所有日志事件被删除了

3:删除所有事件中同一个已命名的回调函数


  1. //利用Backbone.Events方法继承A对象
  2. var A = _.extend({name:"A"},
    Backbone.Events);
  3.  
  4. var foo =
    function
    ()
    {
  5. console.log("foo");
  6. };
  7.  
  8. A.on("log1",foo);
  9. A.on("log2",foo);
  10.  
  11. A.trigger("log1 log2");
    //日志 后台输出foo以及foo
  12. A.off(null,foo);
    //删除所有事件的foo回调
  13. A.trigger("log1 log2");
    //日志无,因为所有foo回调被删除了

 4:删除包含特定文本的所有事件


  1. //利用Backbone.Events方法继承B对象
  2. var B = _.extend({},
    Backbone.Events);
  3. var C =
    {}
  4.  
  5. B.on("logFoo",function
    ()
    {
  6. console.log("foo");
  7. },C);
  8.  
  9. B.on("logBar",function
    ()
    {
  10. console.log("bar");
  11. },C);
  12.  
  13. B.trigger("logFoo logBar");
    //日志 后台输出foo以及bar
  14. B.off(null,null,C);
    //删除包含C文本的所有事件
  15. B.trigger("logFoo logBar");
    //日志无,因为所有包含C文本的事件被删除了

 5:删除一个对象的所有事件和回调


  1. //利用Backbone.Events方法继承B对象
  2. var B = _.extend({},
    Backbone.Events);
  3.  
  4. B.on("logFoo",function
    ()
    {
  5. console.log("foo");
  6. });
  7.  
  8. B.on("logBar",function
    ()
    {
  9. console.log("bar");
  10. });
  11.  
  12. B.trigger("logFoo logBar");
    //日志 后台输出foo以及bar
  13. B.off();
    //删除B对象的所有事件
  14. B.trigger("logFoo logBar");
    //日志无,因为所有对象B的事件被删除了

 提示:

Backbone model, collection, view, 或 router对象上使用不带参数的off()函数,可以移除BackBone事件和回调中的所有内容。

利用listenTo()让对象B监听对象A的事件

当对象A的事件发生,利用listenTo()方法可以让对象B监听到这个事件,并调用回调函数。在下面的代码中,我让对象B来监听对象A上发生的whosListeningToMe事件,当whosListeningToMe事件发生时将调用whosListeningToMe回调函数。


  1. //利用Backbone.Events方法继承对象A和对象B

  1. var A = _.extend({name:"A"},
    Backbone.Events);
  2. var B = _.extend({name:"B"},
    Backbone.Events);
  3.  
  4. var whosListeningToMe =
    function(){
  5. console.log(this.name);
  6. };
  7.  
  8. //让对象B监听对象A上被触发的whosListeningToMe事件,然后调用whosListeningToMe
  9. B.listenTo(A,
    "whosListeningToMe", whosListeningToMe);
  10.  
  11. A.trigger("whosListeningToMe");
    //日志 B
  12. /*
  13. 对象A没有whosListeningToMe事件,但这个事件能够通告监听者它已经被触发
  14. */

提示:

  1. listenToOnce(other,callback,callback)方法是可用的,其用法类似于listenTo(),不同之处在于listenToOnce(other,callback,callback)的回调函数在被第一次调用过后就被立即移除了,所以监听只发生一次。
  2. 当一个对象事件被触发,不管该对象上是否有事件处理器,任何监听这个事件的其他对象都能被通告这个事件被触发了。

利用stopListening()停止一个对象对另一个对象上所有事件的监听

当一个对象正在监听其他对象时,可以用stopListening()方法进行以下四种处理。

1:停止所有监听


  1. var A = _.extend({name:"A"},
    Backbone.Events);
  2. var B = _.extend({name:"B"},
    Backbone.Events);
  3. var C = _.extend({name:"C"},
    Backbone.Events);
  4.  
  5. var whosListeningToMe =
    function(){console.log(this.name);};
  6.  
  7. //对象B监听对象A和对象C的whosListeningToMe事件
  8. B.listenTo(A,
    "whosListeningToMe", whosListeningToMe);
  9. B.listenTo(C,
    "whosListeningToMe", whosListeningToMe);
  10.  
  11. //触发对象A和对象C上的whosListeningToMe事件
  12. A.trigger("whosListeningToMe");
    //logs B
  13. C.trigger("whosListeningToMe");
    //logs B
  14.  
  15. //让对象B停止监听所有对象
  16. B.stopListening();
  17.  
  18. //日志无,因为我们让对象B停止监听所有内容
  19. A.trigger("whosListeningToMe");
  20. C.trigger("whosListeningToMe");

2:停止对某一特定对象的监听


  1. var A = _.extend({name:"A"},
    Backbone.Events);
  2. var B = _.extend({name:"B"},
    Backbone.Events);
  3. var C = _.extend({name:"C"},
    Backbone.Events);
  4.  
  5. var whosListeningToMe =
    function(){console.log(this.name);};
  6.  
  7. B.listenTo(A,
    "whosListeningToMe", whosListeningToMe);
  8. B.listenTo(C,
    "whosListeningToMe", whosListeningToMe);
  9.  
  10. A.trigger("whosListeningToMe");
    //日志 B
  11. C.trigger("whosListeningToMe");
    //日志 B
  12.  
  13. B.stopListening(A);
  14.  
  15. //因为对象B停止监听对象A,所以后台输出无,但是对象B继续监听对象C
  16. A.trigger("whosListeningToMe");
  17. C.trigger("whosListeningToMe");
    //日志 B

 3:停止监听某一特定对象上的特定事件


  1. var A = _.extend({name:"A"},
    Backbone.Events);
  2. var B = _.extend({name:"B"},
    Backbone.Events);
  3.  
  4. var whosListeningToMe =
    function(){console.log(this.name);};
  5.  
  6. B.listenTo(A,
    "whosListeningToMe", whosListeningToMe);
  7.  
  8. A.trigger("whosListeningToMe");
    //日志 B
  9.  
  10. //让对象B停止监听对象A上的某一特定事件
  11. B.stopListening(A,"whosListeningToMe");
  12. //日志无,因为对象B停止监听对象A上的whosListeningToMe事件
  13. A.trigger("whosListeningToMe");

 4:停止监听特定对象上的某一特定事件和回调


  1. var A = _.extend({name:"A"},
    Backbone.Events);
  2. var B = _.extend({name:"B"},
    Backbone.Events);
  3.  
  4. var whosListeningToMe =
    function(){console.log(this.name);};
  5. var whosListeningToMeAgain =
    function(){console.log(this.name);};
  6.  
  7. B.listenTo(A,
    "whosListeningToMe", whosListeningToMe);
  8. B.listenTo(A,
    "whosListeningToMe", whosListeningToMeAgain);
  9.  
  10. A.trigger("whosListeningToMe");
    //日志 后台输出B 以及B
  11.  
  12. //让对象B停止监听对象A上的特定事件和回调
  13. B.stopListening(A,"whosListeningToMe",whosListeningToMeAgain);
  14.  
  15. A.trigger("whosListeningToMe");
    //日志 B

 Backbone嵌入事件

Backbone触发以下嵌入models, collections, viewsrouter对象的内部事件,因此我们通过Backbone事件的on()listenTo()方法就能运用这些事件,并且有多种多样的运用方式。但现在,我们还是先来回顾一下下表中单独的事件描述,以便更清楚的了解事件在哪种情况下被触发。

model, collection, view, router以及历史对象事件

 

集合对象事件

 

模型对象事件

 

模型或集合对象事件

 

路由器对象事件

 

以上提到的事件,除了‘all"类型事件以外,在本节里都能找到例子详细说明对象上的事件于何种情况下被触发。为了更好掌握Backbone嵌入事件,下面我们将对‘all"事件加以详述。Backbone嵌入事件由Backbone对象触发,一旦Backbone model, collection, view, or router上的任意事件被触发,则‘all"事件就会被触发/广播。

在以下示例中我将演示一个Backbone模型,并在‘all’事件上利用on()绑定了一个回调函数。然后在模型中设定一些数据,模型将广播两个事件:一个‘change"事件和一个‘change:attribute"事件(在上面的表格中可以找到说明)。‘all’事件将被触发两次,因为当两个‘change’事件都被触发的时候,‘all’事件就被广播了两次。


  1. //创建一个默认的模型对象
  2. var myModel =
    new
    Backbone.Model();
  3.  
  4. //绑定一个回调对象到嵌入"all"事件
  5. myModel.on("all",
    function
    (e)
    {
  6. console.log(e);
  7. });
  8.  
  9. //触发‘change"和‘change:attribute"事件,就会触发all两次
  10. myModel.set({"test":"test"});
  11.  
  12. /*利用listenTo()可以达到相同的效果
  13. var A = _.extend({}, Backbone.Events);
  14.  
  15. A.listenTo(myModel, "all", function (e) {
  16. console.log(e);
  17. });
  18. */

正如本小节第一点提到的,all事件能够捕捉到是谁触发了‘all"事件,因此我们可以记录到(日志)哪个事件触发了‘all’事件。

请注意,‘all’事件并非只针对于模型,它能被任意触发了的Backbone内嵌事件触发。然而‘change’事件是专门针对模型的。这个例子有助于宽泛理解开发Backbone应用程序过程中,如何使用所有的嵌入事件。

Backbone.Events总结

从这一小节得到的概念是利用Backbone对象互相通信的通用模式,利用上述方法处理JavaScript对象,你就能掌握如何创建自定义事件,也可以更好的处理Backbone Models, Collections, Views, the Router中被触发的事件。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索对象
, backbone
, 事件
, trigger
, 事件监听
, 监听
, event log
, events
, 四种回调方法
, 回调对象方法
, 监听日志
, off移除事件
, 事件对象
A方法
,以便于您获取更多的相关知识。

时间: 2024-11-03 12:09:09

Backbone.js系列教程五:Backbone.Events的相关文章

Backbone.js系列教程一 - Backbone.js简介

JavaScript在web应用程序开发前端技术和后端技术的逻辑与运行一块占有越来越大的比重.为了帮助维护和循环访问前期逻辑和模块性,MVC模式在近几年中渐渐普及.其中一种运用广泛的MVC框架就是Backbone.js. Backbone中的Models(模型).Views(视图)和Controller(控制器) Backbone.js包含以下几个主要功能: 创建模型(以及模型集合): 创建视图: 管理绑定,管理事件兼用不同的模型以及视图与框架其他部分的联系: 在模型中使用观察者模式,一旦模型触

Backbone.js系列教程九:Backbone实用程序库

利用Backbone.noConflict()存储和创建一个特殊的(就是自定义命名空间)引用到Backbone 当Backbone被浏览器解析时,Backbone做的第一件事就是存储一个引用到包含在全局作用域(也就是window.Backbone)中 的Backbone的值.这是因为Backbone重写或占据了这个命名空间,希望给开发者机会去存储在Backbone被解析之前使用的初值.这就是 Backbone.noConflict()起作用的时候了.调用Backbone.noConflict()

Backbone.js系列教程十:Backbone.View

在前几节中我们介绍了Backbone基础知识,如果你还没有阅读过,那么我建议你从第一节开始学习--Backbone.js系列教程一:Backbone.js初探,尤其希望你能完全理解构造Backbone对象相 关知识,这对于学习今后的内容有很大帮助.在接下来的几个小节中,我们将深入Backbone,讨论Backbone views.models和collections.相信大家在阅读前文之后,已经对Backbone.View.Backbone.Model. Backbone.Collection构

Backbone.js系列教程二:Backbone.js深入解析之基础要求

在网上关于Backbone的描述很少,现有的关于Backbone的内容五花八门,基本上都不同程度的提到了如何运用Backbone来实现应用程序的创建,当然也有很多的是讨论它是否匹配Model/View/Whatever.有挺多华而不实的视频教程是讲程序设计的,但其实没有什么太大的价值.我认为关键是缺少了关于Backbone本身的详细介绍,以及对于每行代码的真正用意的细节描述.有篇文档专门讲述Backbone各部分的功能,在一定程度上解答了上述问题,并且提供带有注释的源代码,还有更多相关Backb

Backbone.js系列教程四:Backbone全面介绍

Backbone的原理 Backbone的初衷在于单页面应用程序中添加架构,尤其是在创造DocumentCloud应 用程序的过程中,以避免重复性的DOM交叉以及DOM中用于保持UI同步的数据发生混乱.Backbone通过一套构造函数来完成这个步骤,于是就形成了 模型.集合与视图对象,目的在于组织应用程序的数据.逻辑和显示.一旦这些对象被具现化,它们彼此之间就存在特殊的关系,共同保证了应用程序的模块化.松 耦合性(利用event系统沟通).可扩展性. Backbone提供应用程序架构,还能帮助构

Backbone.js系列教程六:构造Backbone对象

Backbone构造函数 我之所以说Backbone很简单,是因为Backbone只有四个构造函数能被典型的实例化(基本上,它们首先被继承或子分类).这四种构造函数包括: Backbone.Model = function(attributes, {options}){}; Backbone.Collection = function([models], {options}){}; Backbone.Router = function({options}){}; //只能被具现化一次  Back

Backbone.js系列教程三:深入解析之框架,模型视图

Backbone下的框架设想 Backbone是用于开发SPA(AKA单页应用)环境.你可能想要知道这些是什么.简单的讲,SPA就是一个加载了一个页面 (index.html或者app.html)的web应用,整个应用通过自定义事件,自定义URL句柄,和异步HTTP检索,存储资源来发送到客户端, 这样避免了页面的重复加载.基本上,SPA框架只加载一个HTML页面,因此JavaScript可以用于仿写/重写/编排浏览器上传统web应用框架的 默认属性. 让我们检验Backbone SPA的框架假设

Backbone.js系列教程十二:Backbone.Collection

Backbone.Collection概述 一个Backbone集合表示了一组模型逻辑有序的组合,并提供使用(组合,分类,过滤)这些模型组的方法与属性.在本文中为了说明这样的联系关系 (模型=表单中的一行有标签的联系数据),你可以把一个集合看做是整张表单,其中包含了很多行联系数据.下面我更新了表单中联系内容的细节,在上一章节开 头我们讲述过,于是整张表单能够被当作一个联系表单. 当然,一个Backbone.Collection不仅仅是一个像之前表单表现的那种标签.集合还可以捕捉模型以及集合上被触

Backbone.js系列教程七:Backbone.Router

Backbone.router()概述 一个Backbone route是一个JavaScript字符串,类似于传统认识中的URL路径名. 这个像字符串的路径名是一个函数的属性名(或引用命名函数),当在浏览器中有url与字符串匹配时被调用.举例来说,下例中的url包含路径名 "help" ,在一个单独的Backbone应用页面中它将通告Backbone调用一个函数,这个函数关联了名为'help"的路由. http://www.hostname.com/#help 请注意,路径