HttpProxy.js
上传用户:shuoshiled
上传日期:2018-01-28
资源大小:10124k
文件大小:12k
源码类别:

中间件编程

开发平台:

JavaScript

  1. /*!  * Ext JS Library 3.0.0  * Copyright(c) 2006-2009 Ext JS, LLC  * licensing@extjs.com  * http://www.extjs.com/license  */ /**
  2.  * @class Ext.data.HttpProxy
  3.  * @extends Ext.data.DataProxy
  4.  * <p>An implementation of {@link Ext.data.DataProxy} that processes data requests within the same
  5.  * domain of the originating page.</p>
  6.  * <p><b>Note</b>: this class cannot be used to retrieve data from a domain other
  7.  * than the domain from which the running page was served. For cross-domain requests, use a
  8.  * {@link Ext.data.ScriptTagProxy ScriptTagProxy}.</p>
  9.  * <p>Be aware that to enable the browser to parse an XML document, the server must set
  10.  * the Content-Type header in the HTTP response to "<tt>text/xml</tt>".</p>
  11.  * @constructor
  12.  * @param {Object} conn
  13.  * An {@link Ext.data.Connection} object, or options parameter to {@link Ext.Ajax#request}.
  14.  * <p>Note that if this HttpProxy is being used by a (@link Ext.data.Store Store}, then the
  15.  * Store's call to {@link #load} will override any specified <tt>callback</tt> and <tt>params</tt>
  16.  * options. In this case, use the Store's {@link Ext.data.Store#events events} to modify parameters,
  17.  * or react to loading events. The Store's {@link Ext.data.Store#baseParams baseParams} may also be
  18.  * used to pass parameters known at instantiation time.</p>
  19.  * <p>If an options parameter is passed, the singleton {@link Ext.Ajax} object will be used to make
  20.  * the request.</p>
  21.  */
  22. Ext.data.HttpProxy = function(conn){
  23.     Ext.data.HttpProxy.superclass.constructor.call(this, conn);
  24.     /**
  25.      * The Connection object (Or options parameter to {@link Ext.Ajax#request}) which this HttpProxy
  26.      * uses to make requests to the server. Properties of this object may be changed dynamically to
  27.      * change the way data is requested.
  28.      * @property
  29.      */
  30.     this.conn = conn;
  31.     // nullify the connection url.  The url param has been copied to 'this' above.  The connection
  32.     // url will be set during each execution of doRequest when buildUrl is called.  This makes it easier for users to override the
  33.     // connection url during beforeaction events (ie: beforeload, beforesave, etc).  The connection url will be nullified
  34.     // after each request as well.  Url is always re-defined during doRequest.
  35.     this.conn.url = null;
  36.     this.useAjax = !conn || !conn.events;
  37.     //private.  A hash containing active requests, keyed on action [Ext.data.Api.actions.create|read|update|destroy]
  38.     var actions = Ext.data.Api.actions;
  39.     this.activeRequest = {};
  40.     for (var verb in actions) {
  41.         this.activeRequest[actions[verb]] = undefined;
  42.     }
  43. };
  44. Ext.extend(Ext.data.HttpProxy, Ext.data.DataProxy, {
  45.     /**
  46.      * @cfg {Boolean} restful
  47.      * <p>If set to <tt>true</tt>, a {@link Ext.data.Record#phantom non-phantom} record's
  48.      * {@link Ext.data.Record#id id} will be appended to the url (defaults to <tt>false</tt>).</p><br>
  49.      * <p>The url is built based upon the action being executed <tt>[load|create|save|destroy]</tt>
  50.      * using the commensurate <tt>{@link #api}</tt> property, or if undefined default to the
  51.      * configured {@link Ext.data.Store}.{@link Ext.data.Store#url url}.</p><br>
  52.      * <p>Some MVC (e.g., Ruby on Rails, Merb and Django) support this style of segment based urls
  53.      * where the segments in the URL follow the Model-View-Controller approach.</p><pre><code>
  54.      * someSite.com/controller/action/id
  55.      * </code></pre>
  56.      * Where the segments in the url are typically:<div class="mdetail-params"><ul>
  57.      * <li>The first segment : represents the controller class that should be invoked.</li>
  58.      * <li>The second segment : represents the class function, or method, that should be called.</li>
  59.      * <li>The third segment : represents the ID (a variable typically passed to the method).</li>
  60.      * </ul></div></p>
  61.      * <p>For example:</p>
  62.      * <pre><code>
  63. api: {
  64.     load :    '/controller/load',
  65.     create :  '/controller/new',  // Server MUST return idProperty of new record
  66.     save :    '/controller/update',
  67.     destroy : '/controller/destroy_action'
  68. }
  69. // Alternatively, one can use the object-form to specify each API-action
  70. api: {
  71.     load: {url: 'read.php', method: 'GET'},
  72.     create: 'create.php',
  73.     destroy: 'destroy.php',
  74.     save: 'update.php'
  75. }
  76.      */
  77.     /**
  78.      * Return the {@link Ext.data.Connection} object being used by this Proxy.
  79.      * @return {Connection} The Connection object. This object may be used to subscribe to events on
  80.      * a finer-grained basis than the DataProxy events.
  81.      */
  82.     getConnection : function() {
  83.         return this.useAjax ? Ext.Ajax : this.conn;
  84.     },
  85.     /**
  86.      * Used for overriding the url used for a single request.  Designed to be called during a beforeaction event.  Calling setUrl
  87.      * will override any urls set via the api configuration parameter.  Set the optional parameter makePermanent to set the url for
  88.      * all subsequent requests.  If not set to makePermanent, the next request will use the same url or api configuration defined
  89.      * in the initial proxy configuration.
  90.      * @param {String} url
  91.      * @param {Boolean} makePermanent (Optional) [false]
  92.      *
  93.      * (e.g.: beforeload, beforesave, etc).
  94.      */
  95.     setUrl : function(url, makePermanent) {
  96.         this.conn.url = url;
  97.         if (makePermanent === true) {
  98.             this.url = url;
  99.             Ext.data.Api.prepare(this);
  100.         }
  101.     },
  102.     /**
  103.      * HttpProxy implementation of DataProxy#doRequest
  104.      * @param {String} action The crud action type (create, read, update, destroy)
  105.      * @param {Ext.data.Record/Ext.data.Record[]} rs If action is load, rs will be null
  106.      * @param {Object} params An object containing properties which are to be used as HTTP parameters
  107.      * for the request to the remote server.
  108.      * @param {Ext.data.DataReader} reader The Reader object which converts the data
  109.      * object into a block of Ext.data.Records.
  110.      * @param {Function} callback
  111.      * <div class="sub-desc"><p>A function to be called after the request.
  112.      * The <tt>callback</tt> is passed the following arguments:<ul>
  113.      * <li><tt>r</tt> : Ext.data.Record[] The block of Ext.data.Records.</li>
  114.      * <li><tt>options</tt>: Options object from the action request</li>
  115.      * <li><tt>success</tt>: Boolean success indicator</li></ul></p></div>
  116.      * @param {Object} scope The scope in which to call the callback
  117.      * @param {Object} arg An optional argument which is passed to the callback as its second parameter.
  118.      */
  119.     doRequest : function(action, rs, params, reader, cb, scope, arg) {
  120.         var  o = {
  121.             method: (this.api[action]) ? this.api[action]['method'] : undefined,
  122.             request: {
  123.                 callback : cb,
  124.                 scope : scope,
  125.                 arg : arg
  126.             },
  127.             reader: reader,
  128.             callback : this.createCallback(action, rs),
  129.             scope: this
  130.         };
  131.         // Sample the request data:  If it's an object, then it hasn't been json-encoded yet.
  132.         // Transmit data using jsonData config of Ext.Ajax.request
  133.         if (typeof(params[reader.meta.root]) === 'object') {
  134.             o.jsonData = params;
  135.         } else {
  136.             o.params = params || {};
  137.         }
  138.         // Set the connection url.  If this.conn.url is not null here,
  139.         // the user may have overridden the url during a beforeaction event-handler.
  140.         // this.conn.url is nullified after each request.
  141.         if (this.conn.url === null) {
  142.             this.conn.url = this.buildUrl(action, rs);
  143.         }
  144.         else if (this.restful === true && rs instanceof Ext.data.Record && !rs.phantom) {
  145.             this.conn.url += '/' + rs.id;
  146.         }
  147.         if(this.useAjax){
  148.             Ext.applyIf(o, this.conn);
  149.             // If a currently running request is found for this action, abort it.
  150.             if (this.activeRequest[action]) {
  151.                 // Disabled aborting activeRequest while implementing REST.  activeRequest[action] will have to become an array
  152.                 //Ext.Ajax.abort(this.activeRequest[action]);
  153.             }
  154.             this.activeRequest[action] = Ext.Ajax.request(o);
  155.         }else{
  156.             this.conn.request(o);
  157.         }
  158.         // request is sent, nullify the connection url in preparation for the next request
  159.         this.conn.url = null;
  160.     },
  161.     /**
  162.      * Returns a callback function for a request.  Note a special case is made for the
  163.      * read action vs all the others.
  164.      * @param {String} action [create|update|delete|load]
  165.      * @param {Ext.data.Record[]} rs The Store-recordset being acted upon
  166.      * @private
  167.      */
  168.     createCallback : function(action, rs) {
  169.         return function(o, success, response) {
  170.             this.activeRequest[action] = undefined;
  171.             if (!success) {
  172.                 if (action === Ext.data.Api.actions.read) {
  173.                     // @deprecated: fire loadexception for backwards compat.
  174.                     this.fireEvent('loadexception', this, o, response);
  175.                 }
  176.                 this.fireEvent('exception', this, 'response', action, o, response);
  177.                 o.request.callback.call(o.request.scope, null, o.request.arg, false);
  178.                 return;
  179.             }
  180.             if (action === Ext.data.Api.actions.read) {
  181.                 this.onRead(action, o, response);
  182.             } else {
  183.                 this.onWrite(action, o, response, rs);
  184.             }
  185.         }
  186.     },
  187.     /**
  188.      * Callback for read action
  189.      * @param {String} action Action name as per {@link Ext.data.Api.actions#read}.
  190.      * @param {Object} o The request transaction object
  191.      * @param {Object} res The server response
  192.      * @private
  193.      */
  194.     onRead : function(action, o, response) {
  195.         var result;
  196.         try {
  197.             result = o.reader.read(response);
  198.         }catch(e){
  199.             // @deprecated: fire old loadexception for backwards-compat.
  200.             this.fireEvent('loadexception', this, o, response, e);
  201.             this.fireEvent('exception', this, 'response', action, o, response, e);
  202.             o.request.callback.call(o.request.scope, null, o.request.arg, false);
  203.             return;
  204.         }
  205.         if (result.success === false) {
  206.             // @deprecated: fire old loadexception for backwards-compat.
  207.             this.fireEvent('loadexception', this, o, response);
  208.             // Get DataReader read-back a response-object to pass along to exception event
  209.             var res = o.reader.readResponse(action, response);
  210.             this.fireEvent('exception', this, 'remote', action, o, res, null);
  211.         }
  212.         else {
  213.             this.fireEvent('load', this, o, o.request.arg);
  214.         }
  215.         o.request.callback.call(o.request.scope, result, o.request.arg, result.success);
  216.     },
  217.     /**
  218.      * Callback for write actions
  219.      * @param {String} action [Ext.data.Api.actions.create|read|update|destroy]
  220.      * @param {Object} trans The request transaction object
  221.      * @param {Object} res The server response
  222.      * @private
  223.      */
  224.     onWrite : function(action, o, response, rs) {
  225.         var reader = o.reader;
  226.         var res;
  227.         try {
  228.             res = reader.readResponse(action, response);
  229.         } catch (e) {
  230.             this.fireEvent('exception', this, 'response', action, o, response, e);
  231.             o.request.callback.call(o.request.scope, null, o.request.arg, false);
  232.             return;
  233.         }
  234.         if (res[reader.meta.successProperty] === false) {
  235.             this.fireEvent('exception', this, 'remote', action, o, res, rs);
  236.         } else {
  237.             this.fireEvent('write', this, action, res[reader.meta.root], res, rs, o.request.arg);
  238.         }
  239.         o.request.callback.call(o.request.scope, res[reader.meta.root], res, res[reader.meta.successProperty]);
  240.     },
  241.     // inherit docs
  242.     destroy: function(){
  243.         if(!this.useAjax){
  244.             this.conn.abort();
  245.         }else if(this.activeRequest){
  246.             var actions = Ext.data.Api.actions;
  247.             for (var verb in actions) {
  248.                 if(this.activeRequest[actions[verb]]){
  249.                     Ext.Ajax.abort(this.activeRequest[actions[verb]]);
  250.                 }
  251.             }
  252.         }
  253.         Ext.data.HttpProxy.superclass.destroy.call(this);
  254.     }
  255. });