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