data-foundation-debug.js
上传用户:dawnssy
上传日期:2022-08-06
资源大小:9345k
文件大小:179k
源码类别:

JavaScript

开发平台:

JavaScript

  1.      * @cfg {Function} doRequest Abstract method that should be implemented in all subclasses.  <b>Note:</b> Should only be used by custom-proxy developers.
  2.      * (e.g.: {@link Ext.data.HttpProxy#doRequest HttpProxy.doRequest},
  3.      * {@link Ext.data.DirectProxy#doRequest DirectProxy.doRequest}).
  4.      */
  5.     doRequest : function(action, rs, params, reader, callback, scope, options) {
  6.         // default implementation of doRequest for backwards compatibility with 2.0 proxies.
  7.         // If we're executing here, the action is probably "load".
  8.         // Call with the pre-3.0 method signature.
  9.         this.load(params, reader, callback, scope, options);
  10.     },
  11.     /**
  12.      * @cfg {Function} onRead Abstract method that should be implemented in all subclasses.  <b>Note:</b> Should only be used by custom-proxy developers.  Callback for read {@link Ext.data.Api#actions action}.
  13.      * @param {String} action Action name as per {@link Ext.data.Api.actions#read}.
  14.      * @param {Object} o The request transaction object
  15.      * @param {Object} res The server response
  16.      * @fires loadexception (deprecated)
  17.      * @fires exception
  18.      * @fires load
  19.      * @protected
  20.      */
  21.     onRead : Ext.emptyFn,
  22.     /**
  23.      * @cfg {Function} onWrite Abstract method that should be implemented in all subclasses.  <b>Note:</b> Should only be used by custom-proxy developers.  Callback for <i>create, update and destroy</i> {@link Ext.data.Api#actions actions}.
  24.      * @param {String} action [Ext.data.Api.actions.create|read|update|destroy]
  25.      * @param {Object} trans The request transaction object
  26.      * @param {Object} res The server response
  27.      * @fires exception
  28.      * @fires write
  29.      * @protected
  30.      */
  31.     onWrite : Ext.emptyFn,
  32.     /**
  33.      * buildUrl
  34.      * Sets the appropriate url based upon the action being executed.  If restful is true, and only a single record is being acted upon,
  35.      * url will be built Rails-style, as in "/controller/action/32".  restful will aply iff the supplied record is an
  36.      * instance of Ext.data.Record rather than an Array of them.
  37.      * @param {String} action The api action being executed [read|create|update|destroy]
  38.      * @param {Ext.data.Record/Array[Ext.data.Record]} The record or Array of Records being acted upon.
  39.      * @return {String} url
  40.      * @private
  41.      */
  42.     buildUrl : function(action, record) {
  43.         record = record || null;
  44.         // conn.url gets nullified after each request.  If it's NOT null here, that means the user must have intervened with a call
  45.         // to DataProxy#setUrl or DataProxy#setApi and changed it before the request was executed.  If that's the case, use conn.url,
  46.         // otherwise, build the url from the api or this.url.
  47.         var url = (this.conn && this.conn.url) ? this.conn.url : (this.api[action]) ? this.api[action].url : this.url;
  48.         if (!url) {
  49.             throw new Ext.data.Api.Error('invalid-url', action);
  50.         }
  51.         // look for urls having "provides" suffix used in some MVC frameworks like Rails/Merb and others.  The provides suffice informs
  52.         // the server what data-format the client is dealing with and returns data in the same format (eg: application/json, application/xml, etc)
  53.         // e.g.: /users.json, /users.xml, etc.
  54.         // with restful routes, we need urls like:
  55.         // PUT /users/1.json
  56.         // DELETE /users/1.json
  57.         var provides = null;
  58.         var m = url.match(/(.*)(.json|.xml|.html)$/);
  59.         if (m) {
  60.             provides = m[2];    // eg ".json"
  61.             url      = m[1];    // eg: "/users"
  62.         }
  63.         // prettyUrls is deprectated in favor of restful-config
  64.         if ((this.restful === true || this.prettyUrls === true) && record instanceof Ext.data.Record && !record.phantom) {
  65.             url += '/' + record.id;
  66.         }
  67.         return (provides === null) ? url : url + provides;
  68.     },
  69.     /**
  70.      * Destroys the proxy by purging any event listeners and cancelling any active requests.
  71.      */
  72.     destroy: function(){
  73.         this.purgeListeners();
  74.     }
  75. });
  76. // Apply the Observable prototype to the DataProxy class so that proxy instances can relay their
  77. // events to the class.  Allows for centralized listening of all proxy instances upon the DataProxy class.
  78. Ext.apply(Ext.data.DataProxy, Ext.util.Observable.prototype);
  79. Ext.util.Observable.call(Ext.data.DataProxy);
  80. /**
  81.  * @class Ext.data.DataProxy.Error
  82.  * @extends Ext.Error
  83.  * DataProxy Error extension.
  84.  * constructor
  85.  * @param {String} name
  86.  * @param {Record/Array[Record]/Array}
  87.  */
  88. Ext.data.DataProxy.Error = Ext.extend(Ext.Error, {
  89.     constructor : function(message, arg) {
  90.         this.arg = arg;
  91.         Ext.Error.call(this, message);
  92.     },
  93.     name: 'Ext.data.DataProxy'
  94. });
  95. Ext.apply(Ext.data.DataProxy.Error.prototype, {
  96.     lang: {
  97.         'action-undefined': "DataProxy attempted to execute an API-action but found an undefined url / function.  Please review your Proxy url/api-configuration.",
  98.         'api-invalid': 'Recieved an invalid API-configuration.  Please ensure your proxy API-configuration contains only the actions from Ext.data.Api.actions.'
  99.     }
  100. });
  101. /**  * @class Ext.data.Request  * A simple Request class used internally to the data package to provide more generalized remote-requests  * to a DataProxy.  * TODO Not yet implemented.  Implement in Ext.data.Store#execute  */ Ext.data.Request = function(params) {     Ext.apply(this, params); }; Ext.data.Request.prototype = {     /**      * @cfg {String} action      */     action : undefined,     /**      * @cfg {Ext.data.Record[]/Ext.data.Record} rs The Store recordset associated with the request.      */     rs : undefined,     /**      * @cfg {Object} params HTTP request params      */     params: undefined,     /**      * @cfg {Function} callback The function to call when request is complete      */     callback : Ext.emptyFn,     /**      * @cfg {Object} scope The scope of the callback funtion      */     scope : undefined,     /**      * @cfg {Ext.data.DataReader} reader The DataReader instance which will parse the received response      */     reader : undefined }; /**  * @class Ext.data.Response  * A generic response class to normalize response-handling internally to the framework.  */ Ext.data.Response = function(params) {     Ext.apply(this, params); }; Ext.data.Response.prototype = {     /**      * @cfg {String} action {@link Ext.data.Api#actions}      */     action: undefined,     /**      * @cfg {Boolean} success      */     success : undefined,     /**      * @cfg {String} message      */     message : undefined,     /**      * @cfg {Array/Object} data      */     data: undefined,     /**      * @cfg {Object} raw The raw response returned from server-code      */     raw: undefined,     /**      * @cfg {Ext.data.Record/Ext.data.Record[]} records related to the Request action      */     records: undefined }; /**
  102.  * @class Ext.data.ScriptTagProxy
  103.  * @extends Ext.data.DataProxy
  104.  * An implementation of Ext.data.DataProxy that reads a data object from a URL which may be in a domain
  105.  * other than the originating domain of the running page.<br>
  106.  * <p>
  107.  * <b>Note that if you are retrieving data from a page that is in a domain that is NOT the same as the originating domain
  108.  * of the running page, you must use this class, rather than HttpProxy.</b><br>
  109.  * <p>
  110.  * The content passed back from a server resource requested by a ScriptTagProxy <b>must</b> be executable JavaScript
  111.  * source code because it is used as the source inside a &lt;script> tag.<br>
  112.  * <p>
  113.  * In order for the browser to process the returned data, the server must wrap the data object
  114.  * with a call to a callback function, the name of which is passed as a parameter by the ScriptTagProxy.
  115.  * Below is a Java example for a servlet which returns data for either a ScriptTagProxy, or an HttpProxy
  116.  * depending on whether the callback name was passed:
  117.  * <p>
  118.  * <pre><code>
  119. boolean scriptTag = false;
  120. String cb = request.getParameter("callback");
  121. if (cb != null) {
  122.     scriptTag = true;
  123.     response.setContentType("text/javascript");
  124. } else {
  125.     response.setContentType("application/x-json");
  126. }
  127. Writer out = response.getWriter();
  128. if (scriptTag) {
  129.     out.write(cb + "(");
  130. }
  131. out.print(dataBlock.toJsonString());
  132. if (scriptTag) {
  133.     out.write(");");
  134. }
  135. </code></pre>
  136.  * <p>Below is a PHP example to do the same thing:</p><pre><code>
  137. $callback = $_REQUEST['callback'];
  138. // Create the output object.
  139. $output = array('a' => 'Apple', 'b' => 'Banana');
  140. //start output
  141. if ($callback) {
  142.     header('Content-Type: text/javascript');
  143.     echo $callback . '(' . json_encode($output) . ');';
  144. } else {
  145.     header('Content-Type: application/x-json');
  146.     echo json_encode($output);
  147. }
  148. </code></pre>
  149.  *
  150.  * @constructor
  151.  * @param {Object} config A configuration object.
  152.  */
  153. Ext.data.ScriptTagProxy = function(config){
  154.     Ext.apply(this, config);
  155.     Ext.data.ScriptTagProxy.superclass.constructor.call(this, config);
  156.     this.head = document.getElementsByTagName("head")[0];
  157.     /**
  158.      * @event loadexception
  159.      * <b>Deprecated</b> in favor of 'exception' event.
  160.      * Fires if an exception occurs in the Proxy during data loading.  This event can be fired for one of two reasons:
  161.      * <ul><li><b>The load call timed out.</b>  This means the load callback did not execute within the time limit
  162.      * specified by {@link #timeout}.  In this case, this event will be raised and the
  163.      * fourth parameter (read error) will be null.</li>
  164.      * <li><b>The load succeeded but the reader could not read the response.</b>  This means the server returned
  165.      * data, but the configured Reader threw an error while reading the data.  In this case, this event will be
  166.      * raised and the caught error will be passed along as the fourth parameter of this event.</li></ul>
  167.      * Note that this event is also relayed through {@link Ext.data.Store}, so you can listen for it directly
  168.      * on any Store instance.
  169.      * @param {Object} this
  170.      * @param {Object} options The loading options that were specified (see {@link #load} for details).  If the load
  171.      * call timed out, this parameter will be null.
  172.      * @param {Object} arg The callback's arg object passed to the {@link #load} function
  173.      * @param {Error} e The JavaScript Error object caught if the configured Reader could not read the data.
  174.      * If the remote request returns success: false, this parameter will be null.
  175.      */
  176. };
  177. Ext.data.ScriptTagProxy.TRANS_ID = 1000;
  178. Ext.extend(Ext.data.ScriptTagProxy, Ext.data.DataProxy, {
  179.     /**
  180.      * @cfg {String} url The URL from which to request the data object.
  181.      */
  182.     /**
  183.      * @cfg {Number} timeout (optional) The number of milliseconds to wait for a response. Defaults to 30 seconds.
  184.      */
  185.     timeout : 30000,
  186.     /**
  187.      * @cfg {String} callbackParam (Optional) The name of the parameter to pass to the server which tells
  188.      * the server the name of the callback function set up by the load call to process the returned data object.
  189.      * Defaults to "callback".<p>The server-side processing must read this parameter value, and generate
  190.      * javascript output which calls this named function passing the data object as its only parameter.
  191.      */
  192.     callbackParam : "callback",
  193.     /**
  194.      *  @cfg {Boolean} nocache (optional) Defaults to true. Disable caching by adding a unique parameter
  195.      * name to the request.
  196.      */
  197.     nocache : true,
  198.     /**
  199.      * HttpProxy implementation of DataProxy#doRequest
  200.      * @param {String} action
  201.      * @param {Ext.data.Record/Ext.data.Record[]} rs If action is <tt>read</tt>, rs will be null
  202.      * @param {Object} params An object containing properties which are to be used as HTTP parameters
  203.      * for the request to the remote server.
  204.      * @param {Ext.data.DataReader} reader The Reader object which converts the data
  205.      * object into a block of Ext.data.Records.
  206.      * @param {Function} callback The function into which to pass the block of Ext.data.Records.
  207.      * The function must be passed <ul>
  208.      * <li>The Record block object</li>
  209.      * <li>The "arg" argument from the load function</li>
  210.      * <li>A boolean success indicator</li>
  211.      * </ul>
  212.      * @param {Object} scope The scope (<code>this</code> reference) in which the callback function is executed. Defaults to the browser window.
  213.      * @param {Object} arg An optional argument which is passed to the callback as its second parameter.
  214.      */
  215.     doRequest : function(action, rs, params, reader, callback, scope, arg) {
  216.         var p = Ext.urlEncode(Ext.apply(params, this.extraParams));
  217.         var url = this.buildUrl(action, rs);
  218.         if (!url) {
  219.             throw new Ext.data.Api.Error('invalid-url', url);
  220.         }
  221.         url = Ext.urlAppend(url, p);
  222.         if(this.nocache){
  223.             url = Ext.urlAppend(url, '_dc=' + (new Date().getTime()));
  224.         }
  225.         var transId = ++Ext.data.ScriptTagProxy.TRANS_ID;
  226.         var trans = {
  227.             id : transId,
  228.             action: action,
  229.             cb : "stcCallback"+transId,
  230.             scriptId : "stcScript"+transId,
  231.             params : params,
  232.             arg : arg,
  233.             url : url,
  234.             callback : callback,
  235.             scope : scope,
  236.             reader : reader
  237.         };
  238.         window[trans.cb] = this.createCallback(action, rs, trans);
  239.         url += String.format("&{0}={1}", this.callbackParam, trans.cb);
  240.         if(this.autoAbort !== false){
  241.             this.abort();
  242.         }
  243.         trans.timeoutId = this.handleFailure.defer(this.timeout, this, [trans]);
  244.         var script = document.createElement("script");
  245.         script.setAttribute("src", url);
  246.         script.setAttribute("type", "text/javascript");
  247.         script.setAttribute("id", trans.scriptId);
  248.         this.head.appendChild(script);
  249.         this.trans = trans;
  250.     },
  251.     // @private createCallback
  252.     createCallback : function(action, rs, trans) {
  253.         var self = this;
  254.         return function(res) {
  255.             self.trans = false;
  256.             self.destroyTrans(trans, true);
  257.             if (action === Ext.data.Api.actions.read) {
  258.                 self.onRead.call(self, action, trans, res);
  259.             } else {
  260.                 self.onWrite.call(self, action, trans, res, rs);
  261.             }
  262.         };
  263.     },
  264.     /**
  265.      * Callback for read actions
  266.      * @param {String} action [Ext.data.Api.actions.create|read|update|destroy]
  267.      * @param {Object} trans The request transaction object
  268.      * @param {Object} res The server response
  269.      * @protected
  270.      */
  271.     onRead : function(action, trans, res) {
  272.         var result;
  273.         try {
  274.             result = trans.reader.readRecords(res);
  275.         }catch(e){
  276.             // @deprecated: fire loadexception
  277.             this.fireEvent("loadexception", this, trans, res, e);
  278.             this.fireEvent('exception', this, 'response', action, trans, res, e);
  279.             trans.callback.call(trans.scope||window, null, trans.arg, false);
  280.             return;
  281.         }
  282.         if (result.success === false) {
  283.             // @deprecated: fire old loadexception for backwards-compat.
  284.             this.fireEvent('loadexception', this, trans, res);
  285.             this.fireEvent('exception', this, 'remote', action, trans, res, null);
  286.         } else {
  287.             this.fireEvent("load", this, res, trans.arg);
  288.         }
  289.         trans.callback.call(trans.scope||window, result, trans.arg, result.success);
  290.     },
  291.     /**
  292.      * Callback for write actions
  293.      * @param {String} action [Ext.data.Api.actions.create|read|update|destroy]
  294.      * @param {Object} trans The request transaction object
  295.      * @param {Object} res The server response
  296.      * @protected
  297.      */
  298.     onWrite : function(action, trans, response, rs) {
  299.         var reader = trans.reader;
  300.         try {
  301.             // though we already have a response object here in STP, run through readResponse to catch any meta-data exceptions.
  302.             var res = reader.readResponse(action, response);
  303.         } catch (e) {
  304.             this.fireEvent('exception', this, 'response', action, trans, res, e);
  305.             trans.callback.call(trans.scope||window, null, res, false);
  306.             return;
  307.         }
  308.         if(!res.success === true){
  309.             this.fireEvent('exception', this, 'remote', action, trans, res, rs);
  310.             trans.callback.call(trans.scope||window, null, res, false);
  311.             return;
  312.         }
  313.         this.fireEvent("write", this, action, res.data, res, rs, trans.arg );
  314.         trans.callback.call(trans.scope||window, res.data, res, true);
  315.     },
  316.     // private
  317.     isLoading : function(){
  318.         return this.trans ? true : false;
  319.     },
  320.     /**
  321.      * Abort the current server request.
  322.      */
  323.     abort : function(){
  324.         if(this.isLoading()){
  325.             this.destroyTrans(this.trans);
  326.         }
  327.     },
  328.     // private
  329.     destroyTrans : function(trans, isLoaded){
  330.         this.head.removeChild(document.getElementById(trans.scriptId));
  331.         clearTimeout(trans.timeoutId);
  332.         if(isLoaded){
  333.             window[trans.cb] = undefined;
  334.             try{
  335.                 delete window[trans.cb];
  336.             }catch(e){}
  337.         }else{
  338.             // if hasn't been loaded, wait for load to remove it to prevent script error
  339.             window[trans.cb] = function(){
  340.                 window[trans.cb] = undefined;
  341.                 try{
  342.                     delete window[trans.cb];
  343.                 }catch(e){}
  344.             };
  345.         }
  346.     },
  347.     // private
  348.     handleFailure : function(trans){
  349.         this.trans = false;
  350.         this.destroyTrans(trans, false);
  351.         if (trans.action === Ext.data.Api.actions.read) {
  352.             // @deprecated firing loadexception
  353.             this.fireEvent("loadexception", this, null, trans.arg);
  354.         }
  355.         this.fireEvent('exception', this, 'response', trans.action, {
  356.             response: null,
  357.             options: trans.arg
  358.         });
  359.         trans.callback.call(trans.scope||window, null, trans.arg, false);
  360.     },
  361.     // inherit docs
  362.     destroy: function(){
  363.         this.abort();
  364.         Ext.data.ScriptTagProxy.superclass.destroy.call(this);
  365.     }
  366. });/**
  367.  * @class Ext.data.HttpProxy
  368.  * @extends Ext.data.DataProxy
  369.  * <p>An implementation of {@link Ext.data.DataProxy} that processes data requests within the same
  370.  * domain of the originating page.</p>
  371.  * <p><b>Note</b>: this class cannot be used to retrieve data from a domain other
  372.  * than the domain from which the running page was served. For cross-domain requests, use a
  373.  * {@link Ext.data.ScriptTagProxy ScriptTagProxy}.</p>
  374.  * <p>Be aware that to enable the browser to parse an XML document, the server must set
  375.  * the Content-Type header in the HTTP response to "<tt>text/xml</tt>".</p>
  376.  * @constructor
  377.  * @param {Object} conn
  378.  * An {@link Ext.data.Connection} object, or options parameter to {@link Ext.Ajax#request}.
  379.  * <p>Note that if this HttpProxy is being used by a {@link Ext.data.Store Store}, then the
  380.  * Store's call to {@link #load} will override any specified <tt>callback</tt> and <tt>params</tt>
  381.  * options. In this case, use the Store's {@link Ext.data.Store#events events} to modify parameters,
  382.  * or react to loading events. The Store's {@link Ext.data.Store#baseParams baseParams} may also be
  383.  * used to pass parameters known at instantiation time.</p>
  384.  * <p>If an options parameter is passed, the singleton {@link Ext.Ajax} object will be used to make
  385.  * the request.</p>
  386.  */
  387. Ext.data.HttpProxy = function(conn){
  388.     Ext.data.HttpProxy.superclass.constructor.call(this, conn);
  389.     /**
  390.      * The Connection object (Or options parameter to {@link Ext.Ajax#request}) which this HttpProxy
  391.      * uses to make requests to the server. Properties of this object may be changed dynamically to
  392.      * change the way data is requested.
  393.      * @property
  394.      */
  395.     this.conn = conn;
  396.     // nullify the connection url.  The url param has been copied to 'this' above.  The connection
  397.     // url will be set during each execution of doRequest when buildUrl is called.  This makes it easier for users to override the
  398.     // connection url during beforeaction events (ie: beforeload, beforewrite, etc).
  399.     // Url is always re-defined during doRequest.
  400.     this.conn.url = null;
  401.     this.useAjax = !conn || !conn.events;
  402.     // A hash containing active requests, keyed on action [Ext.data.Api.actions.create|read|update|destroy]
  403.     var actions = Ext.data.Api.actions;
  404.     this.activeRequest = {};
  405.     for (var verb in actions) {
  406.         this.activeRequest[actions[verb]] = undefined;
  407.     }
  408. };
  409. Ext.extend(Ext.data.HttpProxy, Ext.data.DataProxy, {
  410.     /**
  411.      * Return the {@link Ext.data.Connection} object being used by this Proxy.
  412.      * @return {Connection} The Connection object. This object may be used to subscribe to events on
  413.      * a finer-grained basis than the DataProxy events.
  414.      */
  415.     getConnection : function() {
  416.         return this.useAjax ? Ext.Ajax : this.conn;
  417.     },
  418.     /**
  419.      * Used for overriding the url used for a single request.  Designed to be called during a beforeaction event.  Calling setUrl
  420.      * will override any urls set via the api configuration parameter.  Set the optional parameter makePermanent to set the url for
  421.      * all subsequent requests.  If not set to makePermanent, the next request will use the same url or api configuration defined
  422.      * in the initial proxy configuration.
  423.      * @param {String} url
  424.      * @param {Boolean} makePermanent (Optional) [false]
  425.      *
  426.      * (e.g.: beforeload, beforesave, etc).
  427.      */
  428.     setUrl : function(url, makePermanent) {
  429.         this.conn.url = url;
  430.         if (makePermanent === true) {
  431.             this.url = url;
  432.             this.api = null;
  433.             Ext.data.Api.prepare(this);
  434.         }
  435.     },
  436.     /**
  437.      * HttpProxy implementation of DataProxy#doRequest
  438.      * @param {String} action The crud action type (create, read, update, destroy)
  439.      * @param {Ext.data.Record/Ext.data.Record[]} rs If action is load, rs will be null
  440.      * @param {Object} params An object containing properties which are to be used as HTTP parameters
  441.      * for the request to the remote server.
  442.      * @param {Ext.data.DataReader} reader The Reader object which converts the data
  443.      * object into a block of Ext.data.Records.
  444.      * @param {Function} callback
  445.      * <div class="sub-desc"><p>A function to be called after the request.
  446.      * The <tt>callback</tt> is passed the following arguments:<ul>
  447.      * <li><tt>r</tt> : Ext.data.Record[] The block of Ext.data.Records.</li>
  448.      * <li><tt>options</tt>: Options object from the action request</li>
  449.      * <li><tt>success</tt>: Boolean success indicator</li></ul></p></div>
  450.      * @param {Object} scope The scope (<code>this</code> reference) in which the callback function is executed. Defaults to the browser window.
  451.      * @param {Object} arg An optional argument which is passed to the callback as its second parameter.
  452.      * @protected
  453.      */
  454.     doRequest : function(action, rs, params, reader, cb, scope, arg) {
  455.         var  o = {
  456.             method: (this.api[action]) ? this.api[action]['method'] : undefined,
  457.             request: {
  458.                 callback : cb,
  459.                 scope : scope,
  460.                 arg : arg
  461.             },
  462.             reader: reader,
  463.             callback : this.createCallback(action, rs),
  464.             scope: this
  465.         };
  466.         // If possible, transmit data using jsonData || xmlData on Ext.Ajax.request (An installed DataWriter would have written it there.).
  467.         // Use std HTTP params otherwise.
  468.         if (params.jsonData) {
  469.             o.jsonData = params.jsonData;
  470.         } else if (params.xmlData) {
  471.             o.xmlData = params.xmlData;
  472.         } else {
  473.             o.params = params || {};
  474.         }
  475.         // Set the connection url.  If this.conn.url is not null here,
  476.         // the user must have overridden the url during a beforewrite/beforeload event-handler.
  477.         // this.conn.url is nullified after each request.
  478.         this.conn.url = this.buildUrl(action, rs);
  479.         if(this.useAjax){
  480.             Ext.applyIf(o, this.conn);
  481.             // If a currently running request is found for this action, abort it.
  482.             if (this.activeRequest[action]) {
  483.                 ////
  484.                 // Disabled aborting activeRequest while implementing REST.  activeRequest[action] will have to become an array
  485.                 // TODO ideas anyone?
  486.                 //
  487.                 //Ext.Ajax.abort(this.activeRequest[action]);
  488.             }
  489.             this.activeRequest[action] = Ext.Ajax.request(o);
  490.         }else{
  491.             this.conn.request(o);
  492.         }
  493.         // request is sent, nullify the connection url in preparation for the next request
  494.         this.conn.url = null;
  495.     },
  496.     /**
  497.      * Returns a callback function for a request.  Note a special case is made for the
  498.      * read action vs all the others.
  499.      * @param {String} action [create|update|delete|load]
  500.      * @param {Ext.data.Record[]} rs The Store-recordset being acted upon
  501.      * @private
  502.      */
  503.     createCallback : function(action, rs) {
  504.         return function(o, success, response) {
  505.             this.activeRequest[action] = undefined;
  506.             if (!success) {
  507.                 if (action === Ext.data.Api.actions.read) {
  508.                     // @deprecated: fire loadexception for backwards compat.
  509.                     // TODO remove in 3.1
  510.                     this.fireEvent('loadexception', this, o, response);
  511.                 }
  512.                 this.fireEvent('exception', this, 'response', action, o, response);
  513.                 o.request.callback.call(o.request.scope, null, o.request.arg, false);
  514.                 return;
  515.             }
  516.             if (action === Ext.data.Api.actions.read) {
  517.                 this.onRead(action, o, response);
  518.             } else {
  519.                 this.onWrite(action, o, response, rs);
  520.             }
  521.         }
  522.     },
  523.     /**
  524.      * Callback for read action
  525.      * @param {String} action Action name as per {@link Ext.data.Api.actions#read}.
  526.      * @param {Object} o The request transaction object
  527.      * @param {Object} res The server response
  528.      * @fires loadexception (deprecated)
  529.      * @fires exception
  530.      * @fires load
  531.      * @protected
  532.      */
  533.     onRead : function(action, o, response) {
  534.         var result;
  535.         try {
  536.             result = o.reader.read(response);
  537.         }catch(e){
  538.             // @deprecated: fire old loadexception for backwards-compat.
  539.             // TODO remove in 3.1
  540.             this.fireEvent('loadexception', this, o, response, e);
  541.             this.fireEvent('exception', this, 'response', action, o, response, e);
  542.             o.request.callback.call(o.request.scope, null, o.request.arg, false);
  543.             return;
  544.         }
  545.         if (result.success === false) {
  546.             // @deprecated: fire old loadexception for backwards-compat.
  547.             // TODO remove in 3.1
  548.             this.fireEvent('loadexception', this, o, response);
  549.             // Get DataReader read-back a response-object to pass along to exception event
  550.             var res = o.reader.readResponse(action, response);
  551.             this.fireEvent('exception', this, 'remote', action, o, res, null);
  552.         }
  553.         else {
  554.             this.fireEvent('load', this, o, o.request.arg);
  555.         }
  556.         // TODO refactor onRead, onWrite to be more generalized now that we're dealing with Ext.data.Response instance
  557.         // the calls to request.callback(...) in each will have to be made identical.
  558.         // NOTE reader.readResponse does not currently return Ext.data.Response
  559.         o.request.callback.call(o.request.scope, result, o.request.arg, result.success);
  560.     },
  561.     /**
  562.      * Callback for write actions
  563.      * @param {String} action [Ext.data.Api.actions.create|read|update|destroy]
  564.      * @param {Object} trans The request transaction object
  565.      * @param {Object} res The server response
  566.      * @fires exception
  567.      * @fires write
  568.      * @protected
  569.      */
  570.     onWrite : function(action, o, response, rs) {
  571.         var reader = o.reader;
  572.         var res;
  573.         try {
  574.             res = reader.readResponse(action, response);
  575.         } catch (e) {
  576.             this.fireEvent('exception', this, 'response', action, o, response, e);
  577.             o.request.callback.call(o.request.scope, null, o.request.arg, false);
  578.             return;
  579.         }
  580.         if (res.success === false) {
  581.             this.fireEvent('exception', this, 'remote', action, o, res, rs);
  582.         } else {
  583.             this.fireEvent('write', this, action, res.data, res, rs, o.request.arg);
  584.         }
  585.         // TODO refactor onRead, onWrite to be more generalized now that we're dealing with Ext.data.Response instance
  586.         // the calls to request.callback(...) in each will have to be made similar.
  587.         // NOTE reader.readResponse does not currently return Ext.data.Response
  588.         o.request.callback.call(o.request.scope, res.data, res, res.success);
  589.     },
  590.     // inherit docs
  591.     destroy: function(){
  592.         if(!this.useAjax){
  593.             this.conn.abort();
  594.         }else if(this.activeRequest){
  595.             var actions = Ext.data.Api.actions;
  596.             for (var verb in actions) {
  597.                 if(this.activeRequest[actions[verb]]){
  598.                     Ext.Ajax.abort(this.activeRequest[actions[verb]]);
  599.                 }
  600.             }
  601.         }
  602.         Ext.data.HttpProxy.superclass.destroy.call(this);
  603.     }
  604. });/**
  605.  * @class Ext.data.MemoryProxy
  606.  * @extends Ext.data.DataProxy
  607.  * An implementation of Ext.data.DataProxy that simply passes the data specified in its constructor
  608.  * to the Reader when its load method is called.
  609.  * @constructor
  610.  * @param {Object} data The data object which the Reader uses to construct a block of Ext.data.Records.
  611.  */
  612. Ext.data.MemoryProxy = function(data){
  613.     // Must define a dummy api with "read" action to satisfy DataProxy#doRequest and Ext.data.Api#prepare *before* calling super
  614.     var api = {};
  615.     api[Ext.data.Api.actions.read] = true;
  616.     Ext.data.MemoryProxy.superclass.constructor.call(this, {
  617.         api: api
  618.     });
  619.     this.data = data;
  620. };
  621. Ext.extend(Ext.data.MemoryProxy, Ext.data.DataProxy, {
  622.     /**
  623.      * @event loadexception
  624.      * Fires if an exception occurs in the Proxy during data loading. Note that this event is also relayed
  625.      * through {@link Ext.data.Store}, so you can listen for it directly on any Store instance.
  626.      * @param {Object} this
  627.      * @param {Object} arg The callback's arg object passed to the {@link #load} function
  628.      * @param {Object} null This parameter does not apply and will always be null for MemoryProxy
  629.      * @param {Error} e The JavaScript Error object caught if the configured Reader could not read the data
  630.      */
  631.        /**
  632.      * MemoryProxy implementation of DataProxy#doRequest
  633.      * @param {String} action
  634.      * @param {Ext.data.Record/Ext.data.Record[]} rs If action is load, rs will be null
  635.      * @param {Object} params An object containing properties which are to be used as HTTP parameters
  636.      * for the request to the remote server.
  637.      * @param {Ext.data.DataReader} reader The Reader object which converts the data
  638.      * object into a block of Ext.data.Records.
  639.      * @param {Function} callback The function into which to pass the block of Ext.data.Records.
  640.      * The function must be passed <ul>
  641.      * <li>The Record block object</li>
  642.      * <li>The "arg" argument from the load function</li>
  643.      * <li>A boolean success indicator</li>
  644.      * </ul>
  645.      * @param {Object} scope The scope (<code>this</code> reference) in which the callback function is executed. Defaults to the browser window.
  646.      * @param {Object} arg An optional argument which is passed to the callback as its second parameter.
  647.      */
  648.     doRequest : function(action, rs, params, reader, callback, scope, arg) {
  649.         // No implementation for CRUD in MemoryProxy.  Assumes all actions are 'load'
  650.         params = params || {};
  651.         var result;
  652.         try {
  653.             result = reader.readRecords(this.data);
  654.         }catch(e){
  655.             // @deprecated loadexception
  656.             this.fireEvent("loadexception", this, null, arg, e);
  657.             this.fireEvent('exception', this, 'response', action, arg, null, e);
  658.             callback.call(scope, null, arg, false);
  659.             return;
  660.         }
  661.         callback.call(scope, result, arg, true);
  662.     }
  663. });