Observable-more.js
上传用户:shuoshiled
上传日期:2018-01-28
资源大小:10124k
文件大小:6k
源码类别:

中间件编程

开发平台:

JavaScript

  1. /*!  * Ext JS Library 3.0.0  * Copyright(c) 2006-2009 Ext JS, LLC  * licensing@extjs.com  * http://www.extjs.com/license  */ /**
  2.  * @class Ext.util.Observable
  3.  */
  4. Ext.apply(Ext.util.Observable.prototype, function(){    
  5.     // this is considered experimental (along with beforeMethod, afterMethod, removeMethodListener?)
  6.     // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
  7.     // private
  8.     function getMethodEvent(method){
  9.         var e = (this.methodEvents = this.methodEvents ||
  10.         {})[method], returnValue, v, cancel, obj = this;
  11.         
  12.         if (!e) {
  13.             this.methodEvents[method] = e = {};
  14.             e.originalFn = this[method];
  15.             e.methodName = method;
  16.             e.before = [];
  17.             e.after = [];
  18.             
  19.             var makeCall = function(fn, scope, args){
  20.                 if (!Ext.isEmpty(v = fn.apply(scope || obj, args))) {
  21.                     if (Ext.isObject(v)) {
  22.                         returnValue = !Ext.isEmpty(v.returnValue) ? v.returnValue : v;
  23.                         cancel = !!v.cancel;
  24.                     }
  25.                     else 
  26.                         if (v === false) {
  27.                             cancel = true;
  28.                         }
  29.                         else {
  30.                             returnValue = v;
  31.                         }
  32.                 }
  33.             };
  34.             
  35.             this[method] = function(){
  36.                 var args = Ext.toArray(arguments);
  37.                 returnValue = v = undefined;
  38.                 cancel = false;
  39.                 
  40.                 Ext.each(e.before, function(b){
  41.                     makeCall(b.fn, b.scope, args);
  42.                     if (cancel) {
  43.                         return returnValue;
  44.                     }
  45.                 });
  46.                 
  47.                 if (!Ext.isEmpty(v = e.originalFn.apply(obj, args))) {
  48.                     returnValue = v;
  49.                 }
  50.                 Ext.each(e.after, function(a){
  51.                     makeCall(a.fn, a.scope, args);
  52.                     if (cancel) {
  53.                         return returnValue;
  54.                     }
  55.                 });
  56.                 return returnValue;
  57.             };
  58.         }
  59.         return e;
  60.     }
  61.     
  62.     return {
  63.         // these are considered experimental
  64.         // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
  65.         // adds an "interceptor" called before the original method
  66.         beforeMethod: function(method, fn, scope){
  67.             getMethodEvent.call(this, method).before.push({
  68.                 fn: fn,
  69.                 scope: scope
  70.             });
  71.         },
  72.         
  73.         // adds a "sequence" called after the original method
  74.         afterMethod: function(method, fn, scope){
  75.             getMethodEvent.call(this, method).after.push({
  76.                 fn: fn,
  77.                 scope: scope
  78.             });
  79.         },
  80.         
  81.         removeMethodListener: function(method, fn, scope){
  82.             var e = getMethodEvent.call(this, method), found = false;
  83.             Ext.each(e.before, function(b, i, arr){
  84.                 if (b.fn == fn && b.scope == scope) {
  85.                     arr.splice(i, 1);
  86.                     found = true;
  87.                     return false;
  88.                 }
  89.             });
  90.             if (!found) {
  91.                 Ext.each(e.after, function(a, i, arr){
  92.                     if (a.fn == fn && a.scope == scope) {
  93.                         arr.splice(i, 1);
  94.                         return false;
  95.                     }
  96.                 });
  97.             }
  98.         },
  99.         
  100.         /**
  101.          * Relays selected events from the specified Observable as if the events were fired by <tt><b>this</b></tt>.
  102.          * @param {Object} o The Observable whose events this object is to relay.
  103.          * @param {Array} events Array of event names to relay.
  104.          */
  105.         relayEvents: function(o, events){
  106.             var me = this;
  107.             function createHandler(ename){
  108.                 return function(){
  109.                     return me.fireEvent.apply(me, [ename].concat(Ext.toArray(arguments)));
  110.                 };
  111.             }
  112.             Ext.each(events, function(ename){
  113.                 me.events[ename] = me.events[ename] || true;
  114.                 o.on(ename, createHandler(ename), me);
  115.             });
  116.         },
  117.         
  118.         /**
  119.          * Used to enable bubbling of events
  120.          * @param {Object} events
  121.          */
  122.         enableBubble: function(events){
  123.             var me = this;
  124.             events = Ext.isArray(events) ? events : Ext.toArray(arguments);
  125.             Ext.each(events, function(ename){
  126.                 ename = ename.toLowerCase();
  127.                 var ce = me.events[ename] || true;
  128.                 if (typeof ce == "boolean") {
  129.                     ce = new Ext.util.Event(me, ename);
  130.                     me.events[ename] = ce;
  131.                 }
  132.                 ce.bubble = true;
  133.             });
  134.         }
  135.     };
  136. }());
  137. /**
  138.  * Starts capture on the specified Observable. All events will be passed
  139.  * to the supplied function with the event name + standard signature of the event
  140.  * <b>before</b> the event is fired. If the supplied function returns false,
  141.  * the event will not fire.
  142.  * @param {Observable} o The Observable to capture
  143.  * @param {Function} fn The function to call
  144.  * @param {Object} scope (optional) The scope (this object) for the fn
  145.  * @static
  146.  */
  147. Ext.util.Observable.capture = function(o, fn, scope){
  148.     o.fireEvent = o.fireEvent.createInterceptor(fn, scope);
  149. };
  150. /**
  151.  * Sets observability on the passed class constructor.<p>
  152.  * <p>This makes any event fired on any instance of the passed class also fire a single event through
  153.  * the <i>class</i> allowing for central handling of events on many instances at once.</p>
  154.  * <p>Usage:</p><pre><code>
  155. Ext.util.Observable.observeClass(Ext.data.Connection);
  156. Ext.data.Connection.on('beforerequest', function(con, options) {
  157.     console.log("Ajax request made to " + options.url);
  158. });</code></pre>
  159.  * @param {Function} c The class constructor to make observable.
  160.  * @static
  161.  */
  162. Ext.util.Observable.observeClass = function(c){
  163.     Ext.apply(c, new Ext.util.Observable());
  164.     c.prototype.fireEvent = function(){
  165.         return (c.fireEvent.apply(c, arguments) !== false) &&
  166.         (Ext.util.Observable.prototype.fireEvent.apply(this, arguments) !== false);
  167.     };
  168. };