• Event in Backbone


    本文主要讲下Bacbone中的事件系统,先声明一个工具类:

     1 var slice = Array.prototype.slice;
     2     _ = (function () {
     3         var _ = function () { };
     4         _.extend = function (target) {
     5             var sources = slice.call(arguments, 1);
     6             sources.forEach(function (source) {
     7                 if (source) {
     8                     for (var prop in source) {
     9                         target[prop] = source[prop];
    10                     }
    11                 }
    12             });
    13             return target;
    14         }
    15 
    16         var idCounter = 0;
    17         _.uniqueId = function (prefix) {
    18             var id = ++idCounter + '';
    19             return prefix ? prefix + id : id;
    20         };
    21         return _;
    22 })();

    事件系统的大体框架:

     1 jass=(function(){
     2 var bone={};
     3 bone.Events={
     4    on: function (event, callback, context) {
     5    },
     6    off: function (event, callback, context) {
     7    },
     8   listenTo: function (otherObj, event, callback) {
     9   },
    10   stopListening: function (otherObj, event, callback) {
    11   },
    12   trigger: function (event) {
    13   }
    14 
    15 }
    16      return bone;
    17 })();

    on/off方法:

     1       on: function (event, callback, context) {
     2           this._events || (this._events = {});
     3           var events = this._events[event] || (this._events[event] = []);
     4           events.push({ callback: callback, context: context, ctx: context || this });
     5           return this;
     6       },
     7       off: function (event, callback, context) {
     8           if (!event && !callback) {
     9               this._events = {};
    10               return this;
    11           }
    12           delete this._events[event];
    13       }

    这两方法的原理和zepto中的on/off两方法差不多,不同的是,这里不再处理DOM元素上的事件:

     listenTo/stopListening方法:

     1       listenTo: function (otherObj, event, callback) {
     2             var listeners = this._listeners || (this._listeners = {});
     3             var id = otherObj._listenerId || (otherObj._listenerId = _.uniqueId('1'));
     4             listeners[id] = otherObj;
     5             var onlyListener = !event && !callback;
     6             if (onlyListener) return this;
     7 
     8             if (typeof event === 'object') callback = this;
     9 
    10             otherObj.on(event, callback, this);
    11 
    12             return this;
    13       },
    14       stopListening: function (otherObj, event, callback) {
    15             var listeners = this._listeners;
    16             if (!listeners) return;
    17             var deleteListener = !event && !callback;
    18             if (typeof name === 'object') callback = this;
    19             if (otherObj) (listeners = {})[otherObj._listenerId] = otherObj;
    20             for (var id in listeners) {
    21                 listeners[id].off(event, callback, this);
    22                 if (deleteListener) delete this._listeners[id];
    23             }
    24             return this;
    25       }

    我们看到,listenTo是通过本对象给另外一个对象注册事件的.其内部调用了on方法,但是把另外的对象记录在其listeners属性中:这样做的好处可以从stopListening方法就能看到,通过listenTo方法注册的事件,都能通本对象的stopListening方法移除掉其他对象上的事件,消除对其他对象的影响.

    trigger方法:

     1     trigger: function (event) {
     2             if (!this._events) return this;
     3             var args = slice.call(arguments, 1);
     4             var events = this._events[event];
     5 
     6             if (events) {
     7                 events.forEach(function (ev) { 
     8                     ev.callback.apply(ev.ctx, args);
     9                 });
    10             }
    11            //处理all事件
    12             var allEvents = this._events.all;
    13             if (allEvents) {
    14                 allEvents.forEach(function (ev) {
    15                     ev.callback.apply(ev.ctx,args);
    16                 });
    17             }
    18         }

    我们知道,在MVC中,视图层是会被频繁创建的,有创建就会有销毁。那一个视图关闭后,我们是不是要做些什么呢?看一个熟悉的场景:

     1 MyView = Backbone.View.extend({
     2   initialize: function(){
     3     this.listenTo (this.model,’change’, this);
     4   },
     5   render: function(){ ... }
     6 });
     7 
     8 Backbone的view类有个remove方法:
    9 remove: function() { 10 this.$el.remove(); 11 this.stopListening(); 12 return this; 13 }

    看到这个方法,是不是有点要清理view的感觉呢?但是遗憾的是,Backbone是不会调用它的,我们要自己添加一个(dispose/destroy)清理方法来封装这个remove,来帮我们处理销毁一个视图后的善后工作.

    想想这里为何用listenTo,而不用on !

     

  • 相关阅读:
    左右对齐Justify遇到的坑
    JS中的相等性判断===, ==, Object.is()
    JS调用栈的一些总结
    VueI18n
    【转】Webpack 快速上手(下)
    【转】Webpack 快速上手(中)
    【转】Webpack 快速上手(上)
    springboot打包排除指定jar包依赖
    prometheus+grafana搭建
    fbctf 安装部署出现的问题
  • 原文地址:https://www.cnblogs.com/stenson/p/3929081.html
Copyright © 2020-2023  润新知