the5fire

关注Python、Django、Vim、Linux、Web开发、团队管理和互联网--Life is short, we need Python.


backbonejsView中事件绑定源码分析

作者:the5fire | 标签:       | 发布:2013-07-02 7:03 a.m. | 阅读量: 9722, 9421

其实上下文是接上一篇的,因为自己不理解backbone view中的事件绑定所以掉到了自己挖的一个坑里,调了两个晚上。把backbone view部分的代码看了之后才明白。

什么样的坑?

来看简单的实例代码

.. code:: html

<div class="topbar"><span class="search">搜索</span><div>

<div class="content_container">bla bla bla bla</div>

对应的js代码是

.. code:: javascript

var View = Backbone.View.extend({
    $el: $('#content_container'),

    events: {
        'click .search': function(evt){console.log('search')},
    }
});

大概就是这样的一个坑,在不理解backbone绑定事件的情况下,默认以为它是绑定的 .search 这个东西。其实不然。

来看看源码

下面是部分代码

.. code:: javascript

// 984 ~ 990 行代码  backbonejs 1.0.0
var View = Backbone.View = function(options) {
  this.cid = _.uniqueId('view');
  this._configure(options || {});
  this._ensureElement();
  this.initialize.apply(this, arguments);
  this.delegateEvents();  // 这句是重点
};

// ......   省略若干行

// 1054 ~ 1073
delegateEvents: function(events) {
  if (!(events || (events = _.result(this, 'events')))) return this;
  this.undelegateEvents();
  for (var key in events) {
    var method = events[key];
    if (!_.isFunction(method)) method = this[events[key]];
    if (!method) continue;

    var match = key.match(delegateEventSplitter);
    var eventName = match[1], selector = match[2];
    method = _.bind(method, this);
    eventName += '.delegateEvents' + this.cid;
    if (selector === '') {
      this.$el.on(eventName, method);
    } else {
      this.$el.on(eventName, selector, method);  // 这句是重点
    }
  }
  return this;
},

关键点在于后面的那个 delegateEvents 这个函数。该函数的流程是:

  • 判断events这个属性是否定义
  • 先接触这个view中的所有已委托的事件
  • 一些合法性检验,如名称是否合法,是否是函数等
  • 绑定到view实例上
  • 最后就是绑定到 $el

看到这就明白了为啥我的那个search始终无法触发了,因为它在 $el 中根本就选择不到它。

- from the5fire.com
----EOF-----

微信公众号:Python程序员杂谈


其他分类: