PageRenderTime 50ms CodeModel.GetById 26ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 0ms

/ext-4.1.0_b3/src/direct/Manager.js

https://bitbucket.org/srogerf/javascript
JavaScript | 263 lines | 105 code | 26 blank | 132 comment | 18 complexity | 5b55828178403ccfb3be3c9c03c1064e MD5 | raw file
  1/**
  2 * Ext.Direct aims to streamline communication between the client and server by providing a single interface that
  3 * reduces the amount of common code typically required to validate data and handle returned data packets (reading data,
  4 * error conditions, etc).
  5 *
  6 * The Ext.direct namespace includes several classes for a closer integration with the server-side. The Ext.data
  7 * namespace also includes classes for working with Ext.data.Stores which are backed by data from an Ext.Direct method.
  8 *
  9 * # Specification
 10 *
 11 * For additional information consult the [Ext.Direct Specification][1].
 12 *
 13 * # Providers
 14 *
 15 * Ext.Direct uses a provider architecture, where one or more providers are used to transport data to and from the
 16 * server. There are several providers that exist in the core at the moment:
 17 *
 18 * - {@link Ext.direct.JsonProvider JsonProvider} for simple JSON operations
 19 * - {@link Ext.direct.PollingProvider PollingProvider} for repeated requests
 20 * - {@link Ext.direct.RemotingProvider RemotingProvider} exposes server side on the client.
 21 *
 22 * A provider does not need to be invoked directly, providers are added via {@link Ext.direct.Manager}.{@link #addProvider}.
 23 *
 24 * # Router
 25 *
 26 * Ext.Direct utilizes a "router" on the server to direct requests from the client to the appropriate server-side
 27 * method. Because the Ext.Direct API is completely platform-agnostic, you could completely swap out a Java based server
 28 * solution and replace it with one that uses C# without changing the client side JavaScript at all.
 29 *
 30 * # Server side events
 31 *
 32 * Custom events from the server may be handled by the client by adding listeners, for example:
 33 *
 34 *     {"type":"event","name":"message","data":"Successfully polled at: 11:19:30 am"}
 35 *
 36 *     // add a handler for a 'message' event sent by the server
 37 *     Ext.direct.Manager.on('message', function(e){
 38 *         out.append(String.format('<p><i>{0}</i></p>', e.data));
 39 *         out.el.scrollTo('t', 100000, true);
 40 *     });
 41 *
 42 *    [1]: http://sencha.com/products/extjs/extdirect
 43 *
 44 * @singleton
 45 * @alternateClassName Ext.Direct
 46 */
 47Ext.define('Ext.direct.Manager', {
 48
 49    /* Begin Definitions */
 50    singleton: true,
 51
 52    mixins: {
 53        observable: 'Ext.util.Observable'
 54    },
 55
 56    requires: ['Ext.util.MixedCollection'],
 57
 58    statics: {
 59        exceptions: {
 60            TRANSPORT: 'xhr',
 61            PARSE: 'parse',
 62            LOGIN: 'login',
 63            SERVER: 'exception'
 64        }
 65    },
 66
 67    /* End Definitions */
 68
 69    constructor: function(){
 70        var me = this;
 71
 72        me.addEvents(
 73            /**
 74             * @event event
 75             * Fires after an event.
 76             * @param {Ext.direct.Event} e The Ext.direct.Event type that occurred.
 77             * @param {Ext.direct.Provider} provider The {@link Ext.direct.Provider Provider}.
 78             */
 79            'event',
 80            /**
 81             * @event exception
 82             * Fires after an event exception.
 83             * @param {Ext.direct.Event} e The event type that occurred.
 84             */
 85            'exception'
 86        );
 87        me.transactions = new Ext.util.MixedCollection();
 88        me.providers = new Ext.util.MixedCollection();
 89
 90        me.mixins.observable.constructor.call(me);
 91    },
 92
 93    /**
 94     * Adds an Ext.Direct Provider and creates the proxy or stub methods to execute server-side methods. If the provider
 95     * is not already connected, it will auto-connect.
 96     *
 97     *     var pollProv = new Ext.direct.PollingProvider({
 98     *         url: 'php/poll2.php'
 99     *     });
100     *
101     *     Ext.direct.Manager.addProvider({
102     *         "type":"remoting",       // create a {@link Ext.direct.RemotingProvider}
103     *         "url":"php\/router.php", // url to connect to the Ext.Direct server-side router.
104     *         "actions":{              // each property within the actions object represents a Class
105     *             "TestAction":[       // array of methods within each server side Class
106     *             {
107     *                 "name":"doEcho", // name of method
108     *                 "len":1
109     *             },{
110     *                 "name":"multiply",
111     *                 "len":1
112     *             },{
113     *                 "name":"doForm",
114     *                 "formHandler":true, // handle form on server with Ext.Direct.Transaction
115     *                 "len":1
116     *             }]
117     *         },
118     *         "namespace":"myApplication",// namespace to create the Remoting Provider in
119     *     },{
120     *         type: 'polling', // create a {@link Ext.direct.PollingProvider}
121     *         url:  'php/poll.php'
122     *     }, pollProv); // reference to previously created instance
123     *
124     * @param {Ext.direct.Provider/Object...} provider
125     * Accepts any number of Provider descriptions (an instance or config object for
126     * a Provider). Each Provider description instructs Ext.Directhow to create
127     * client-side stub methods.
128     */
129    addProvider : function(provider){
130        var me = this,
131            args = arguments,
132            i = 0,
133            len;
134
135        if (args.length > 1) {
136            for (len = args.length; i < len; ++i) {
137                me.addProvider(args[i]);
138            }
139            return;
140        }
141
142        // if provider has not already been instantiated
143        if (!provider.isProvider) {
144            provider = Ext.create('direct.' + provider.type + 'provider', provider);
145        }
146        me.providers.add(provider);
147        provider.on('data', me.onProviderData, me);
148
149
150        if (!provider.isConnected()) {
151            provider.connect();
152        }
153
154        return provider;
155    },
156
157    /**
158     * Retrieves a {@link Ext.direct.Provider provider} by the **{@link Ext.direct.Provider#id id}** specified when the
159     * provider is {@link #addProvider added}.
160     * @param {String/Ext.direct.Provider} id The id of the provider, or the provider instance.
161     */
162    getProvider : function(id){
163        return id.isProvider ? id : this.providers.get(id);
164    },
165
166    /**
167     * Removes the provider.
168     * @param {String/Ext.direct.Provider} provider The provider instance or the id of the provider.
169     * @return {Ext.direct.Provider} The provider, null if not found.
170     */
171    removeProvider : function(provider){
172        var me = this,
173            providers = me.providers;
174
175        provider = provider.isProvider ? provider : providers.get(provider);
176
177        if (provider) {
178            provider.un('data', me.onProviderData, me);
179            providers.remove(provider);
180            return provider;
181        }
182        return null;
183    },
184
185    /**
186     * Adds a transaction to the manager.
187     * @private
188     * @param {Ext.direct.Transaction} transaction The transaction to add
189     * @return {Ext.direct.Transaction} transaction
190     */
191    addTransaction: function(transaction){
192        this.transactions.add(transaction);
193        return transaction;
194    },
195
196    /**
197     * Removes a transaction from the manager.
198     * @private
199     * @param {String/Ext.direct.Transaction} transaction The transaction/id of transaction to remove
200     * @return {Ext.direct.Transaction} transaction
201     */
202    removeTransaction: function(transaction){
203        transaction = this.getTransaction(transaction);
204        this.transactions.remove(transaction);
205        return transaction;
206    },
207
208    /**
209     * Gets a transaction
210     * @private
211     * @param {String/Ext.direct.Transaction} transaction The transaction/id of transaction to get
212     * @return {Ext.direct.Transaction}
213     */
214    getTransaction: function(transaction){
215        return Ext.isObject(transaction) ? transaction : this.transactions.get(transaction);
216    },
217
218    onProviderData : function(provider, event){
219        var me = this,
220            i = 0,
221            len;
222
223        if (Ext.isArray(event)) {
224            for (len = event.length; i < len; ++i) {
225                me.onProviderData(provider, event[i]);
226            }
227            return;
228        }
229        if (event.name && event.name != 'event' && event.name != 'exception') {
230            me.fireEvent(event.name, event);
231        } else if (event.status === false) {
232            me.fireEvent('exception', event);
233        }
234        me.fireEvent('event', event, provider);
235    },
236    
237    /**
238     * Parses a direct function. It may be passed in a string format, for example:
239     * "MyApp.Person.read".
240     * @protected
241     * @param {String/Function} fn The direct function
242     * @return {Function} The function to use in the direct call. Null if not found
243     */
244    parseMethod: function(fn){
245        if (Ext.isString(fn)) {
246            var parts = fn.split('.'),
247                i = 0,
248                len = parts.length,
249                current = window;
250                
251            while (current && i < len) {
252                current = current[parts[i]];
253                ++i;
254            }
255            fn = Ext.isFunction(current) ? current : null;
256        }
257        return fn || null;
258    }
259    
260}, function(){
261    // Backwards compatibility
262    Ext.Direct = Ext.direct.Manager;
263});