问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

backbone 怎么自定义事件

发布网友 发布时间:2022-05-14 04:26

我来回答

1个回答

热心网友 时间:2022-04-22 14:13

一、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的结构如下

  1
  
  _.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中用到,且仅一处。

  1
  
  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的精华了。
  
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
高中高二物理学习方法大全分享 ...的,原子是静止的B.分子和原子都可以构成物质C.分 ...原子都可以构成物质B.分子的体积比原子体积大C.分 ...A.分子都是由原子构成的,而原子也能直接构成物质B.在化学变_百度... ...原子的说法中,不正确的是( )A.分子可以直接构成物质B.分子在不停... 小米打手打作文是什么意思 ...什么来然后被父母抛弃把他丢在森林,后面好像成为国王这样? 武夷岩茶之野茶--野茶中英文简介 手机可以连键盘吗 如何手机连接电脑键盘 PS中选中了文字,去除框选的快捷键是什么? 小程序中怎么设置带*必须填完才能完成 ps里导入图片怎么去边框 小儿支气管肺炎有没有传染性? 支气管炎传染吗?家里有小孩 炸泡泡糖机子什么地方有 破壁机可以炸泡好的干菜吗 炸长米泡机我想买,多少钱一台?在哪可以买? 宽带连接成功,部分网站无法浏览或网页打不开,如何处理? 58二手车客服24小时客服热线 怎样拨通联通客服电话 58同城的二手车可以买吗? uc搞笑段子评论里ETC什么意思? 拼多多里0元下单后东西没见到钱被商家扣过过去了不退找谁说理去 求推荐黑暗系战斗少女番 微信钱包中吃喝玩乐当中得电影打不开页面是怎么回事 电脑突然自动关机正在修改的照片丢失怎么找回? 电脑里的C盘得照片突然都没有了,怎么找回来啊?(,没有删除,就是它自己突然就消失了,搜都搜不到) 电脑上的图片突然没有了怎么找回? 微信吃喝玩乐待评价打不开? 如何配置backbone的router backbone中model.save提交的值,后台如何获取啊 有人用backbone.js 开发吗 女孩学医最适合的专业 临床医学适合女生学吗? 个体户在电子税务局上面选择哪一种才是税务局代打的发票种类代码? 想调查下大家对工作室代打HLK成就的想法 找一本小说 女主本是古武家族的人,后穿越了,会魔笛,其它不清楚了。 苹果交易猫v2.1.1怎么代打? 求魔笛magi的同人小说!希望是穿越型的! 有没有关于穿越到魔笛的小说主角智商高? 赛尔号代打谱尼真身 魔笛magi之女主穿越 魔笛magi的穿越小说 字要多点的 审组织代码证需要填什么表? 穿越的,女主唤男主七郎爱称的言情小说,女主叫阿瑶的,男主姓宗政的,结局是女主练魔笛反噬死的,是虐的 代打赛尔号 * & 视屏 教 赛尔号 打个大Boss和四大神兽の一切BUG (售一小号66016692(各大Boss全部over)仅售 代打资金证明资信证明 求魔笛magi好看的同人文 cf空格名字2014代码