代码改变世界

backbone 之事件(code 分析)

2013-04-21 17:15  掸尘  阅读(2304)  评论(0编辑  收藏  举报

  四川地震了,表示默哀!也许你们再也不用敲代码或者为了生存而发愁。据说地震表示上天震怒了,要警示什么。我等凡夫俗子无法理解!总之,你们要坚强!

  这个星期,在小组内分享了backbone的东西,想表达东西太多,结果一个也没表达清楚。不管自己的表达能力还是对backbone的理解还都还不够!backbone的自定义事件处理机制还是很强大的,翻着源码看了一下,也没弄清楚什么意思。结果看了一下backbone的单元测试,算是看明白了。所以写单元测试很有必要的。只要不是一次性的项目,在公司还是写写单元测试。不然再过几个月让你看以前项目,会陷入自己写的代码自己都不知道什么意思,那时候会骂自己怎么会写如此烂的代码!

  看一下backbone的 绑定的 方法 on的代码

on: function(name, callback, context) {
      if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
      this._events || (this._events = {});
      var events = this._events[name] || (this._events[name] = []);
      events.push({callback: callback, context: context, ctx: context || this});
      return this;
    },

 你会看到 eventsApi 这个方法,这个方法是干嘛的?答:用来处理绑定多个的事件的 比如你看他的测试 events.js 会有如下的代码

 obj.on('a b c', function() { obj.counter += 1; });
 
obj.on({
      a: increment,
      b: increment,
      c: increment
    }, obj);

 第一个为是空格分割,第二个是key val的对象的形式!绑定多个事件。 如果像这样的  obj.on('event', function() { obj.counter += 1; }); 单个绑定,怎不会调用eventsApi 这个方法!看一下 eventsApi的代码

var eventsApi = function(obj, action, name, rest) {
    if (!name) return true;

    // Handle event maps.
    if (typeof name === 'object') {
      for (var key in name) {
        obj[action].apply(obj, [key, name[key]].concat(rest));
      }
      return false;
    }

    // Handle space separated event names.
    if (eventSplitter.test(name)) {
      var names = name.split(eventSplitter);
      for (var i = 0, l = names.length; i < l; i++) {
        obj[action].apply(obj, [names[i]].concat(rest));
      }
      return false;
    }

    return true;
  };

如果不是 空格隔开或 是对象 就返回true !个人感觉这个方法明没有表达这个方法的意思!希望Jeremy Ashkenas 重构一下建议改为 : multipleEventOn
接着看下面的代码

 this._events || (this._events = {});
      var events = this._events[name] || (this._events[name] = []);
      events.push({callback: callback, context: context, ctx: context || this});

this._events 是存储回调函数, 一个name 可能有多个事件,所以 this._events[name] 是一个数组。var events = this._events[name] || (this._events[name] = []) 这一段代码写的很好,让我写要写更多的行,作者基本功很深!
ok 以上是绑定事件源码!

off 则是除掉回调, off: function(name, callback, context)  其实就是操作 this._events, 如果只传name ,那么name下面的都会被删掉,如果传了name和callback则删掉name下面的callback!

ps:看了backbone的代码,写的挺不错!值得一看!