/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. */
  47. Ext.define('Ext.direct.Manager', {
  48. /* Begin Definitions */
  49. singleton: true,
  50. mixins: {
  51. observable: 'Ext.util.Observable'
  52. },
  53. requires: ['Ext.util.MixedCollection'],
  54. statics: {
  55. exceptions: {
  56. TRANSPORT: 'xhr',
  57. PARSE: 'parse',
  58. LOGIN: 'login',
  59. SERVER: 'exception'
  60. }
  61. },
  62. /* End Definitions */
  63. constructor: function(){
  64. var me = this;
  65. me.addEvents(
  66. /**
  67. * @event event
  68. * Fires after an event.
  69. * @param {Ext.direct.Event} e The Ext.direct.Event type that occurred.
  70. * @param {Ext.direct.Provider} provider The {@link Ext.direct.Provider Provider}.
  71. */
  72. 'event',
  73. /**
  74. * @event exception
  75. * Fires after an event exception.
  76. * @param {Ext.direct.Event} e The event type that occurred.
  77. */
  78. 'exception'
  79. );
  80. me.transactions = new Ext.util.MixedCollection();
  81. me.providers = new Ext.util.MixedCollection();
  82. me.mixins.observable.constructor.call(me);
  83. },
  84. /**
  85. * Adds an Ext.Direct Provider and creates the proxy or stub methods to execute server-side methods. If the provider
  86. * is not already connected, it will auto-connect.
  87. *
  88. * var pollProv = new Ext.direct.PollingProvider({
  89. * url: 'php/poll2.php'
  90. * });
  91. *
  92. * Ext.direct.Manager.addProvider({
  93. * "type":"remoting", // create a {@link Ext.direct.RemotingProvider}
  94. * "url":"php\/router.php", // url to connect to the Ext.Direct server-side router.
  95. * "actions":{ // each property within the actions object represents a Class
  96. * "TestAction":[ // array of methods within each server side Class
  97. * {
  98. * "name":"doEcho", // name of method
  99. * "len":1
  100. * },{
  101. * "name":"multiply",
  102. * "len":1
  103. * },{
  104. * "name":"doForm",
  105. * "formHandler":true, // handle form on server with Ext.Direct.Transaction
  106. * "len":1
  107. * }]
  108. * },
  109. * "namespace":"myApplication",// namespace to create the Remoting Provider in
  110. * },{
  111. * type: 'polling', // create a {@link Ext.direct.PollingProvider}
  112. * url: 'php/poll.php'
  113. * }, pollProv); // reference to previously created instance
  114. *
  115. * @param {Ext.direct.Provider/Object...} provider
  116. * Accepts any number of Provider descriptions (an instance or config object for
  117. * a Provider). Each Provider description instructs Ext.Directhow to create
  118. * client-side stub methods.
  119. */
  120. addProvider : function(provider){
  121. var me = this,
  122. args = arguments,
  123. i = 0,
  124. len;
  125. if (args.length > 1) {
  126. for (len = args.length; i < len; ++i) {
  127. me.addProvider(args[i]);
  128. }
  129. return;
  130. }
  131. // if provider has not already been instantiated
  132. if (!provider.isProvider) {
  133. provider = Ext.create('direct.' + provider.type + 'provider', provider);
  134. }
  135. me.providers.add(provider);
  136. provider.on('data', me.onProviderData, me);
  137. if (!provider.isConnected()) {
  138. provider.connect();
  139. }
  140. return provider;
  141. },
  142. /**
  143. * Retrieves a {@link Ext.direct.Provider provider} by the **{@link Ext.direct.Provider#id id}** specified when the
  144. * provider is {@link #addProvider added}.
  145. * @param {String/Ext.direct.Provider} id The id of the provider, or the provider instance.
  146. */
  147. getProvider : function(id){
  148. return id.isProvider ? id : this.providers.get(id);
  149. },
  150. /**
  151. * Removes the provider.
  152. * @param {String/Ext.direct.Provider} provider The provider instance or the id of the provider.
  153. * @return {Ext.direct.Provider} The provider, null if not found.
  154. */
  155. removeProvider : function(provider){
  156. var me = this,
  157. providers = me.providers;
  158. provider = provider.isProvider ? provider : providers.get(provider);
  159. if (provider) {
  160. provider.un('data', me.onProviderData, me);
  161. providers.remove(provider);
  162. return provider;
  163. }
  164. return null;
  165. },
  166. /**
  167. * Adds a transaction to the manager.
  168. * @private
  169. * @param {Ext.direct.Transaction} transaction The transaction to add
  170. * @return {Ext.direct.Transaction} transaction
  171. */
  172. addTransaction: function(transaction){
  173. this.transactions.add(transaction);
  174. return transaction;
  175. },
  176. /**
  177. * Removes a transaction from the manager.
  178. * @private
  179. * @param {String/Ext.direct.Transaction} transaction The transaction/id of transaction to remove
  180. * @return {Ext.direct.Transaction} transaction
  181. */
  182. removeTransaction: function(transaction){
  183. transaction = this.getTransaction(transaction);
  184. this.transactions.remove(transaction);
  185. return transaction;
  186. },
  187. /**
  188. * Gets a transaction
  189. * @private
  190. * @param {String/Ext.direct.Transaction} transaction The transaction/id of transaction to get
  191. * @return {Ext.direct.Transaction}
  192. */
  193. getTransaction: function(transaction){
  194. return Ext.isObject(transaction) ? transaction : this.transactions.get(transaction);
  195. },
  196. onProviderData : function(provider, event){
  197. var me = this,
  198. i = 0,
  199. len;
  200. if (Ext.isArray(event)) {
  201. for (len = event.length; i < len; ++i) {
  202. me.onProviderData(provider, event[i]);
  203. }
  204. return;
  205. }
  206. if (event.name && event.name != 'event' && event.name != 'exception') {
  207. me.fireEvent(event.name, event);
  208. } else if (event.status === false) {
  209. me.fireEvent('exception', event);
  210. }
  211. me.fireEvent('event', event, provider);
  212. },
  213. /**
  214. * Parses a direct function. It may be passed in a string format, for example:
  215. * "MyApp.Person.read".
  216. * @protected
  217. * @param {String/Function} fn The direct function
  218. * @return {Function} The function to use in the direct call. Null if not found
  219. */
  220. parseMethod: function(fn){
  221. if (Ext.isString(fn)) {
  222. var parts = fn.split('.'),
  223. i = 0,
  224. len = parts.length,
  225. current = window;
  226. while (current && i < len) {
  227. current = current[parts[i]];
  228. ++i;
  229. }
  230. fn = Ext.isFunction(current) ? current : null;
  231. }
  232. return fn || null;
  233. }
  234. }, function(){
  235. // Backwards compatibility
  236. Ext.Direct = Ext.direct.Manager;
  237. });