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 @@
/** - * @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; });