Backbone.Events


Backbone中Events的中只有3個方法,分別是on, off, trigger,十分清晰,也沒有其他依賴,下面我們來分析一下。
 
Events 是一個可以被mix到任意對象的模塊,它擁有讓對象綁定和觸發自定義事件的能力。 事件在被綁定之前是不需要事先聲明的,還可以攜帶參數。我們通過一個例子來看:

var object = {};

_.extend(object, Backbone.Events);

object.bind("alert", function(msg) {
  alert("Triggered " + msg);
});
關鍵是_.extend ,調用了underscore中的extend的方法,又是extend下面是underscore從第690行開始的
 
//復制source對象中的所有屬性覆蓋到destination對象上,他是按照循序的,所以最后源將重寫在前面參數相同名稱的屬性
  _.extend = function(obj) {
    each(slice.call(arguments, 1), function(source) {
      for (var prop in source) {
        obj[prop] = source[prop];
      }
    });
    return obj;
  };
 
 

    /**
     * Events 是一個可以被mix到任意對象的模塊,
     * 它擁有讓對象綁定和觸發自定義事件的能力。
     * 事件在被綁定之前是不需要事先聲明的,
     * 還可以攜帶參數。我們通過一個例子來看:
     *  var object = {};
     *    _.extend(object, Backbone.Events);
     *        object.bind("alert", function(msg) {
     *                alert("Triggered " + msg);
     *        });
     *   object.trigger("alert", "www.csser.com");
     * **/
    var Events = Backbone.Events = {

        /**
         * 綁定 callback 函數到 object 對象。 當事件觸發時執行回調函數 callback 。
         * 如果一個頁面中有大量不同的事件,按照慣例使用冒號指定命名空間
         * : "poll:start", 或 "change:selection"
         * */
        on:function (events, callback, context) {
            var calls, event, list;
            if (!callback) return this;

            events = events.split(eventSplitter);

            calls = this._callbacks || (this._callbacks = {});
            //保存回調函數,與事件 到對象的_callbacks上
            while (event = events.shift()) {
                //取出每個事件名放到_callbacks作用對象的屬性,然后把回調函數push到這個數組中
                list = calls[event] || (calls[event] = []);
                list.push(callback, context);
            }

            return this;
        },

        /**
         * 刪除一個或許多回調。如果“上下文”是null,刪除所有的回調  
         * 與功能。如果“回調”是null,刪除所有的回調 
         * 事件。如果“事件”是null,移除所有綁定回所有事件
         *
         * object.unbind("change", onChange);  只移除onChange回調函數
         *  object.unbind("change");           移除所有 "change" 回調函數
         * object.unbind();                    移除對象的所有回調函數
         *
         * **/
        off:function (events, callback, context) {
            var event, calls, list, i;

            // No events, or removing *all* events.
            if (!(calls = this._callbacks)) return this;
            if (!(events || callback || context)) {
                delete this._callbacks;
                return this;
            }

            events = events ? events.split(eventSplitter) : _.keys(calls);

            // Loop through the callback list, splicing where appropriate.
            while (event = events.shift()) {
                if (!(list = calls[event]) || !(callback || context)) {
                    delete calls[event];
                    continue;
                }

                for (i = list.length - 2; i >= 0; i -= 2) {
                    if (!(callback && list[i] !== callback || context && list[i + 1] !== context)) {
                        list.splice(i, 2);
                    }
                }
            }

            return this;
        },

        /**
         * / /觸發一個或許多事件,解雇所有綁定回調。回調是  
         * / /通過相同的參數作為“觸發”是,除了事件的名字  
         * / /(除非你監聽的“所有”,這將導致你的回調  
         * / /接收真實的事件名稱作為第一個參數)。
         * **/
        trigger:function (events) {
            var event, calls, list, i, length, args, all, rest;
            if (!(calls = this._callbacks)) return this;

            rest = [];
            //事件分解
            events = events.split(eventSplitter);

            // Fill up `rest` with the callback arguments.  Since we're only copying
            // the tail of `arguments`, a loop is much faster than Array#slice.
            for (i = 1, length = arguments.length; i < length; i++) {
                rest[i - 1] = arguments[i];
            }

            // For each event, walk through the list of callbacks twice, first to
            // trigger the event, then to trigger any `"all"` callbacks.
            while (event = events.shift()) {
                //復制回調列表來防止修改
                if (all = calls.all) all = all.slice();
                if (list = calls[event]) list = list.slice();

                // 執行事件回調
                if (list) {
                    for (i = 0, length = list.length; i < length; i += 2) {
                        list[i].apply(list[i + 1] || this, rest);
                    }
                }

                // 執行 "all" 回調.
                if (all) {
                    args = [event].concat(rest);
                    for (i = 0, length = all.length; i < length; i += 2) {
                        all[i].apply(all[i + 1] || this, args);
                    }
                }
            }

            return this;
        }

    };

    //別名
    Events.bind = Events.on;
    Events.unbind = Events.off;

 
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM