X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/6746dc89c47ed01b165cc1152533605f97eb8e8d..refs/heads/master:/docs/source/Manager2.html diff --git a/docs/source/Manager2.html b/docs/source/Manager2.html index f1139470..842703bf 100644 --- a/docs/source/Manager2.html +++ b/docs/source/Manager2.html @@ -3,8 +3,8 @@ The source code - - + + @@ -15,310 +15,244 @@ -
/**
- * @class Ext.fx.Manager
- * Animation Manager which keeps track of all current animations and manages them on a frame by frame basis.
- * @private
+  
/**
+ * Ext.Direct aims to streamline communication between the client and server by providing a single interface that
+ * reduces the amount of common code typically required to validate data and handle returned data packets (reading data,
+ * error conditions, etc).
+ *
+ * The Ext.direct namespace includes several classes for a closer integration with the server-side. The Ext.data
+ * namespace also includes classes for working with Ext.data.Stores which are backed by data from an Ext.Direct method.
+ *
+ * # Specification
+ *
+ * For additional information consult the [Ext.Direct Specification][1].
+ *
+ * # Providers
+ *
+ * Ext.Direct uses a provider architecture, where one or more providers are used to transport data to and from the
+ * server. There are several providers that exist in the core at the moment:
+ *
+ * - {@link Ext.direct.JsonProvider JsonProvider} for simple JSON operations
+ * - {@link Ext.direct.PollingProvider PollingProvider} for repeated requests
+ * - {@link Ext.direct.RemotingProvider RemotingProvider} exposes server side on the client.
+ *
+ * A provider does not need to be invoked directly, providers are added via {@link Ext.direct.Manager}.{@link #addProvider}.
+ *
+ * # Router
+ *
+ * Ext.Direct utilizes a "router" on the server to direct requests from the client to the appropriate server-side
+ * method. Because the Ext.Direct API is completely platform-agnostic, you could completely swap out a Java based server
+ * solution and replace it with one that uses C# without changing the client side JavaScript at all.
+ *
+ * # Server side events
+ *
+ * Custom events from the server may be handled by the client by adding listeners, for example:
+ *
+ *     {"type":"event","name":"message","data":"Successfully polled at: 11:19:30 am"}
+ *
+ *     // add a handler for a 'message' event sent by the server
+ *     Ext.direct.Manager.on('message', function(e){
+ *         out.append(String.format('<p><i>{0}</i></p>', e.data));
+ *         out.el.scrollTo('t', 100000, true);
+ *     });
+ *
+ *    [1]: http://sencha.com/products/extjs/extdirect
+ *
  * @singleton
+ * @alternateClassName Ext.Direct
  */
-
-Ext.define('Ext.fx.Manager', {
+Ext.define('Ext.direct.Manager', {
 
     /* Begin Definitions */
-
     singleton: true,
 
-    requires: ['Ext.util.MixedCollection',
-               'Ext.fx.target.Element',
-               'Ext.fx.target.CompositeElement',
-               'Ext.fx.target.Sprite',
-               'Ext.fx.target.CompositeSprite',
-               'Ext.fx.target.Component'],
-
     mixins: {
-        queue: 'Ext.fx.Queue'
+        observable: 'Ext.util.Observable'
     },
 
-    /* End Definitions */
+    requires: ['Ext.util.MixedCollection'],
 
-    constructor: function() {
-        this.items = Ext.create('Ext.util.MixedCollection');
-        this.mixins.queue.constructor.call(this);
-
-        // this.requestAnimFrame = (function() {
-        //     var raf = window.requestAnimationFrame ||
-        //               window.webkitRequestAnimationFrame ||
-        //               window.mozRequestAnimationFrame ||
-        //               window.oRequestAnimationFrame ||
-        //               window.msRequestAnimationFrame;
-        //     if (raf) {
-        //         return function(callback, element) {
-        //             raf(callback);
-        //         };
-        //     }
-        //     else {
-        //         return function(callback, element) {
-        //             window.setTimeout(callback, Ext.fx.Manager.interval);
-        //         };
-        //     }
-        // })();
+    statics: {
+        exceptions: {
+            TRANSPORT: 'xhr',
+            PARSE: 'parse',
+            LOGIN: 'login',
+            SERVER: 'exception'
+        }
     },
 
-    /**
-     * @cfg {Number} interval Default interval in miliseconds to calculate each frame.  Defaults to 16ms (~60fps)
-     */
-    interval: 16,
+    /* End Definitions */
 
-    /**
-     * @cfg {Boolean} forceJS Turn off to not use CSS3 transitions when they are available
-     */
-    forceJS: true,
+    constructor: function(){
+        var me = this;
+
+        me.addEvents(
+            /**
+             * @event event
+             * Fires after an event.
+             * @param {Ext.direct.Event} e The Ext.direct.Event type that occurred.
+             * @param {Ext.direct.Provider} provider The {@link Ext.direct.Provider Provider}.
+             */
+            'event',
+            /**
+             * @event exception
+             * Fires after an event exception.
+             * @param {Ext.direct.Event} e The event type that occurred.
+             */
+            'exception'
+        );
+        me.transactions = Ext.create('Ext.util.MixedCollection');
+        me.providers = Ext.create('Ext.util.MixedCollection');
+
+        me.mixins.observable.constructor.call(me);
+    },
 
-    // @private Target factory
-    createTarget: function(target) {
+    /**
+     * Adds an Ext.Direct Provider and creates the proxy or stub methods to execute server-side methods. If the provider
+     * is not already connected, it will auto-connect.
+     *
+     *     var pollProv = new Ext.direct.PollingProvider({
+     *         url: 'php/poll2.php'
+     *     });
+     *
+     *     Ext.direct.Manager.addProvider({
+     *         "type":"remoting",       // create a {@link Ext.direct.RemotingProvider}
+     *         "url":"php\/router.php", // url to connect to the Ext.Direct server-side router.
+     *         "actions":{              // each property within the actions object represents a Class
+     *             "TestAction":[       // array of methods within each server side Class
+     *             {
+     *                 "name":"doEcho", // name of method
+     *                 "len":1
+     *             },{
+     *                 "name":"multiply",
+     *                 "len":1
+     *             },{
+     *                 "name":"doForm",
+     *                 "formHandler":true, // handle form on server with Ext.Direct.Transaction
+     *                 "len":1
+     *             }]
+     *         },
+     *         "namespace":"myApplication",// namespace to create the Remoting Provider in
+     *     },{
+     *         type: 'polling', // create a {@link Ext.direct.PollingProvider}
+     *         url:  'php/poll.php'
+     *     }, pollProv); // reference to previously created instance
+     *
+     * @param {Ext.direct.Provider/Object...} provider
+     * Accepts any number of Provider descriptions (an instance or config object for
+     * a Provider). Each Provider description instructs Ext.Directhow to create
+     * client-side stub methods.
+     */
+    addProvider : function(provider){
         var me = this,
-            useCSS3 = !me.forceJS && Ext.supports.Transitions,
-            targetObj;
+            args = arguments,
+            i = 0,
+            len;
 
-        me.useCSS3 = useCSS3;
-
-        // dom id
-        if (Ext.isString(target)) {
-            target = Ext.get(target);
-        }
-        // dom element
-        if (target && target.tagName) {
-            target = Ext.get(target);
-            targetObj = Ext.create('Ext.fx.target.' + 'Element' + (useCSS3 ? 'CSS' : ''), target);
-            me.targets.add(targetObj);
-            return targetObj;
-        }
-        if (Ext.isObject(target)) {
-            // Element
-            if (target.dom) {
-                targetObj = Ext.create('Ext.fx.target.' + 'Element' + (useCSS3 ? 'CSS' : ''), target);
+        if (args.length > 1) {
+            for (len = args.length; i < len; ++i) {
+                me.addProvider(args[i]);
             }
-            // Element Composite
-            else if (target.isComposite) {
-                targetObj = Ext.create('Ext.fx.target.' + 'CompositeElement' + (useCSS3 ? 'CSS' : ''), target);
-            }
-            // Draw Sprite
-            else if (target.isSprite) {
-                targetObj = Ext.create('Ext.fx.target.Sprite', target);
-            }
-            // Draw Sprite Composite
-            else if (target.isCompositeSprite) {
-                targetObj = Ext.create('Ext.fx.target.CompositeSprite', target);
-            }
-            // Component
-            else if (target.isComponent) {
-                targetObj = Ext.create('Ext.fx.target.Component', target);
-            }
-            else if (target.isAnimTarget) {
-                return target;
-            }
-            else {
-                return null;
-            }
-            me.targets.add(targetObj);
-            return targetObj;
-        }
-        else {
-            return null;
+            return;
         }
-    },
-
-    /**
-     * Add an Anim to the manager. This is done automatically when an Anim instance is created.
-     * @param {Ext.fx.Anim} anim
-     */
-    addAnim: function(anim) {
-        var items = this.items,
-            task = this.task;
-        // var me = this,
-        //     items = me.items,
-        //     cb = function() {
-        //         if (items.length) {
-        //             me.task = true;
-        //             me.runner();
-        //             me.requestAnimFrame(cb);
-        //         }
-        //         else {
-        //             me.task = false;
-        //         }
-        //     };
-
-        items.add(anim);
 
-        // Start the timer if not already running
-        if (!task && items.length) {
-            task = this.task = {
-                run: this.runner,
-                interval: this.interval,
-                scope: this
-            };
-            Ext.TaskManager.start(task);
+        // if provider has not already been instantiated
+        if (!provider.isProvider) {
+            provider = Ext.create('direct.' + provider.type + 'provider', provider);
         }
+        me.providers.add(provider);
+        provider.on('data', me.onProviderData, me);
 
-        // //Start the timer if not already running
-        // if (!me.task && items.length) {
-        //     me.requestAnimFrame(cb);
-        // }
-    },
 
-    /**
-     * Remove an Anim from the manager. This is done automatically when an Anim ends.
-     * @param {Ext.fx.Anim} anim
-     */
-    removeAnim: function(anim) {
-        // this.items.remove(anim);
-        var items = this.items,
-            task = this.task;
-        items.remove(anim);
-        // Stop the timer if there are no more managed Anims
-        if (task && !items.length) {
-            Ext.TaskManager.stop(task);
-            delete this.task;
+        if (!provider.isConnected()) {
+            provider.connect();
         }
-    },
 
-    /**
-     * @private
-     * Filter function to determine which animations need to be started
-     */
-    startingFilter: function(o) {
-        return o.paused === false && o.running === false && o.iterations > 0;
+        return provider;
     },
 
-    /**
-     * @private
-     * Filter function to determine which animations are still running
+    /**
+     * Retrieves a {@link Ext.direct.Provider provider} by the **{@link Ext.direct.Provider#id id}** specified when the
+     * provider is {@link #addProvider added}.
+     * @param {String/Ext.direct.Provider} id The id of the provider, or the provider instance.
      */
-    runningFilter: function(o) {
-        return o.paused === false && o.running === true && o.isAnimator !== true;
+    getProvider : function(id){
+        return id.isProvider ? id : this.providers.get(id);
     },
 
-    /**
-     * @private
-     * Runner function being called each frame
+    /**
+     * Removes the provider.
+     * @param {String/Ext.direct.Provider} provider The provider instance or the id of the provider.
+     * @return {Ext.direct.Provider} The provider, null if not found.
      */
-    runner: function() {
+    removeProvider : function(provider){
         var me = this,
-            items = me.items;
-
-        me.targetData = {};
-        me.targetArr = {};
+            providers = me.providers;
 
-        // Single timestamp for all animations this interval
-        me.timestamp = new Date();
+        provider = provider.isProvider ? provider : providers.get(provider);
 
-        // Start any items not current running
-        items.filterBy(me.startingFilter).each(me.startAnim, me);
-
-        // Build the new attributes to be applied for all targets in this frame
-        items.filterBy(me.runningFilter).each(me.runAnim, me);
-
-        // Apply all the pending changes to their targets
-        me.applyPendingAttrs();
+        if (provider) {
+            provider.un('data', me.onProviderData, me);
+            providers.remove(provider);
+            return provider;
+        }
+        return null;
     },
 
-    /**
-     * @private
-     * Start the individual animation (initialization)
+    /**
+     * Adds a transaction to the manager.
+     * @private
+     * @param {Ext.direct.Transaction} transaction The transaction to add
+     * @return {Ext.direct.Transaction} transaction
      */
-    startAnim: function(anim) {
-        anim.start(this.timestamp);
+    addTransaction: function(transaction){
+        this.transactions.add(transaction);
+        return transaction;
     },
 
-    /**
-     * @private
-     * Run the individual animation for this frame
+    /**
+     * Removes a transaction from the manager.
+     * @private
+     * @param {String/Ext.direct.Transaction} transaction The transaction/id of transaction to remove
+     * @return {Ext.direct.Transaction} transaction
      */
-    runAnim: function(anim) {
-        if (!anim) {
-            return;
-        }
-        var me = this,
-            targetId = anim.target.getId(),
-            useCSS3 = me.useCSS3 && anim.target.type == 'element',
-            elapsedTime = me.timestamp - anim.startTime,
-            target, o;
-
-        this.collectTargetData(anim, elapsedTime, useCSS3);
-
-        // For CSS3 animation, we need to immediately set the first frame's attributes without any transition
-        // to get a good initial state, then add the transition properties and set the final attributes.
-        if (useCSS3) {
-            // Flush the collected attributes, without transition
-            anim.target.setAttr(me.targetData[targetId], true);
-
-            // Add the end frame data
-            me.targetData[targetId] = [];
-            me.collectTargetData(anim, anim.duration, useCSS3);
-
-            // Pause the animation so runAnim doesn't keep getting called
-            anim.paused = true;
-
-            target = anim.target.target;
-            // We only want to attach an event on the last element in a composite
-            if (anim.target.isComposite) {
-                target = anim.target.target.last();
-            }
-
-            // Listen for the transitionend event
-            o = {};
-            o[Ext.supports.CSS3TransitionEnd] = anim.lastFrame;
-            o.scope = anim;
-            o.single = true;
-            target.on(o);
-        }
-        // For JS animation, trigger the lastFrame handler if this is the final frame
-        else if (elapsedTime >= anim.duration) {
-            me.applyPendingAttrs(true);
-            delete me.targetData[targetId];
-            delete me.targetArr[targetId];
-            anim.lastFrame();
-        }
+    removeTransaction: function(transaction){
+        transaction = this.getTransaction(transaction);
+        this.transactions.remove(transaction);
+        return transaction;
     },
 
-    /**
-     * Collect target attributes for the given Anim object at the given timestamp
-     * @param {Ext.fx.Anim} anim The Anim instance
-     * @param {Number} timestamp Time after the anim's start time
+    /**
+     * Gets a transaction
+     * @private
+     * @param {String/Ext.direct.Transaction} transaction The transaction/id of transaction to get
+     * @return {Ext.direct.Transaction}
      */
-    collectTargetData: function(anim, elapsedTime, useCSS3) {
-        var targetId = anim.target.getId(),
-            targetData = this.targetData[targetId],
-            data;
-        
-        if (!targetData) {
-            targetData = this.targetData[targetId] = [];
-            this.targetArr[targetId] = anim.target;
-        }
-
-        data = {
-            duration: anim.duration,
-            easing: (useCSS3 && anim.reverse) ? anim.easingFn.reverse().toCSS3() : anim.easing,
-            attrs: {}
-        };
-        Ext.apply(data.attrs, anim.runAnim(elapsedTime));
-        targetData.push(data);
+    getTransaction: function(transaction){
+        return transaction.isTransaction ? transaction : this.transactions.get(transaction);
     },
 
-    /**
-     * @private
-     * Apply all pending attribute changes to their targets
-     */
-    applyPendingAttrs: function(isLastFrame) {
-        var targetData = this.targetData,
-            targetArr = this.targetArr,
-            targetId;
-        for (targetId in targetData) {
-            if (targetData.hasOwnProperty(targetId)) {
-                targetArr[targetId].setAttr(targetData[targetId], false, isLastFrame);
+    onProviderData : function(provider, event){
+        var me = this,
+            i = 0,
+            len;
+
+        if (Ext.isArray(event)) {
+            for (len = event.length; i < len; ++i) {
+                me.onProviderData(provider, event[i]);
             }
+            return;
+        }
+        if (event.name && event.name != 'event' && event.name != 'exception') {
+            me.fireEvent(event.name, event);
+        } else if (event.status === false) {
+            me.fireEvent('exception', event);
         }
+        me.fireEvent('event', event, provider);
     }
+}, function(){
+    // Backwards compatibility
+    Ext.Direct = Ext.direct.Manager;
 });