[76] | 1 | /*! |
---|
| 2 | * Ext JS Library 3.4.0 |
---|
| 3 | * Copyright(c) 2006-2011 Sencha Inc. |
---|
| 4 | * licensing@sencha.com |
---|
| 5 | * http://www.sencha.com/license |
---|
| 6 | */ |
---|
| 7 | /** |
---|
| 8 | * @class Ext.data.DataProxy |
---|
| 9 | * @extends Ext.util.Observable |
---|
| 10 | * <p>Abstract base class for implementations which provide retrieval of unformatted data objects. |
---|
| 11 | * This class is intended to be extended and should not be created directly. For existing implementations, |
---|
| 12 | * see {@link Ext.data.DirectProxy}, {@link Ext.data.HttpProxy}, {@link Ext.data.ScriptTagProxy} and |
---|
| 13 | * {@link Ext.data.MemoryProxy}.</p> |
---|
| 14 | * <p>DataProxy implementations are usually used in conjunction with an implementation of {@link Ext.data.DataReader} |
---|
| 15 | * (of the appropriate type which knows how to parse the data object) to provide a block of |
---|
| 16 | * {@link Ext.data.Records} to an {@link Ext.data.Store}.</p> |
---|
| 17 | * <p>The parameter to a DataProxy constructor may be an {@link Ext.data.Connection} or can also be the |
---|
| 18 | * config object to an {@link Ext.data.Connection}.</p> |
---|
| 19 | * <p>Custom implementations must implement either the <code><b>doRequest</b></code> method (preferred) or the |
---|
| 20 | * <code>load</code> method (deprecated). See |
---|
| 21 | * {@link Ext.data.HttpProxy}.{@link Ext.data.HttpProxy#doRequest doRequest} or |
---|
| 22 | * {@link Ext.data.HttpProxy}.{@link Ext.data.HttpProxy#load load} for additional details.</p> |
---|
| 23 | * <p><b><u>Example 1</u></b></p> |
---|
| 24 | * <pre><code> |
---|
| 25 | proxy: new Ext.data.ScriptTagProxy({ |
---|
| 26 | {@link Ext.data.Connection#url url}: 'http://extjs.com/forum/topics-remote.php' |
---|
| 27 | }), |
---|
| 28 | * </code></pre> |
---|
| 29 | * <p><b><u>Example 2</u></b></p> |
---|
| 30 | * <pre><code> |
---|
| 31 | proxy : new Ext.data.HttpProxy({ |
---|
| 32 | {@link Ext.data.Connection#method method}: 'GET', |
---|
| 33 | {@link Ext.data.HttpProxy#prettyUrls prettyUrls}: false, |
---|
| 34 | {@link Ext.data.Connection#url url}: 'local/default.php', // see options parameter for {@link Ext.Ajax#request} |
---|
| 35 | {@link #api}: { |
---|
| 36 | // all actions except the following will use above url |
---|
| 37 | create : 'local/new.php', |
---|
| 38 | update : 'local/update.php' |
---|
| 39 | } |
---|
| 40 | }), |
---|
| 41 | * </code></pre> |
---|
| 42 | * <p>And <b>new in Ext version 3</b>, attach centralized event-listeners upon the DataProxy class itself! This is a great place |
---|
| 43 | * to implement a <i>messaging system</i> to centralize your application's user-feedback and error-handling.</p> |
---|
| 44 | * <pre><code> |
---|
| 45 | // Listen to all "beforewrite" event fired by all proxies. |
---|
| 46 | Ext.data.DataProxy.on('beforewrite', function(proxy, action) { |
---|
| 47 | console.log('beforewrite: ', action); |
---|
| 48 | }); |
---|
| 49 | |
---|
| 50 | // Listen to "write" event fired by all proxies |
---|
| 51 | Ext.data.DataProxy.on('write', function(proxy, action, data, res, rs) { |
---|
| 52 | console.info('write: ', action); |
---|
| 53 | }); |
---|
| 54 | |
---|
| 55 | // Listen to "exception" event fired by all proxies |
---|
| 56 | Ext.data.DataProxy.on('exception', function(proxy, type, action, exception) { |
---|
| 57 | console.error(type + action + ' exception); |
---|
| 58 | }); |
---|
| 59 | * </code></pre> |
---|
| 60 | * <b>Note:</b> These three events are all fired with the signature of the corresponding <i>DataProxy instance</i> event {@link #beforewrite beforewrite}, {@link #write write} and {@link #exception exception}. |
---|
| 61 | */ |
---|
| 62 | Ext.data.DataProxy = function(conn){ |
---|
| 63 | // make sure we have a config object here to support ux proxies. |
---|
| 64 | // All proxies should now send config into superclass constructor. |
---|
| 65 | conn = conn || {}; |
---|
| 66 | |
---|
| 67 | // This line caused a bug when people use custom Connection object having its own request method. |
---|
| 68 | // http://extjs.com/forum/showthread.php?t=67194. Have to set DataProxy config |
---|
| 69 | //Ext.applyIf(this, conn); |
---|
| 70 | |
---|
| 71 | this.api = conn.api; |
---|
| 72 | this.url = conn.url; |
---|
| 73 | this.restful = conn.restful; |
---|
| 74 | this.listeners = conn.listeners; |
---|
| 75 | |
---|
| 76 | // deprecated |
---|
| 77 | this.prettyUrls = conn.prettyUrls; |
---|
| 78 | |
---|
| 79 | /** |
---|
| 80 | * @cfg {Object} api |
---|
| 81 | * Specific urls to call on CRUD action methods "read", "create", "update" and "destroy". |
---|
| 82 | * Defaults to:<pre><code> |
---|
| 83 | api: { |
---|
| 84 | read : undefined, |
---|
| 85 | create : undefined, |
---|
| 86 | update : undefined, |
---|
| 87 | destroy : undefined |
---|
| 88 | } |
---|
| 89 | * </code></pre> |
---|
| 90 | * <p>The url is built based upon the action being executed <tt>[load|create|save|destroy]</tt> |
---|
| 91 | * using the commensurate <tt>{@link #api}</tt> property, or if undefined default to the |
---|
| 92 | * configured {@link Ext.data.Store}.{@link Ext.data.Store#url url}.</p><br> |
---|
| 93 | * <p>For example:</p> |
---|
| 94 | * <pre><code> |
---|
| 95 | api: { |
---|
| 96 | load : '/controller/load', |
---|
| 97 | create : '/controller/new', // Server MUST return idProperty of new record |
---|
| 98 | save : '/controller/update', |
---|
| 99 | destroy : '/controller/destroy_action' |
---|
| 100 | } |
---|
| 101 | |
---|
| 102 | // Alternatively, one can use the object-form to specify each API-action |
---|
| 103 | api: { |
---|
| 104 | load: {url: 'read.php', method: 'GET'}, |
---|
| 105 | create: 'create.php', |
---|
| 106 | destroy: 'destroy.php', |
---|
| 107 | save: 'update.php' |
---|
| 108 | } |
---|
| 109 | * </code></pre> |
---|
| 110 | * <p>If the specific URL for a given CRUD action is undefined, the CRUD action request |
---|
| 111 | * will be directed to the configured <tt>{@link Ext.data.Connection#url url}</tt>.</p> |
---|
| 112 | * <br><p><b>Note</b>: To modify the URL for an action dynamically the appropriate API |
---|
| 113 | * property should be modified before the action is requested using the corresponding before |
---|
| 114 | * action event. For example to modify the URL associated with the load action: |
---|
| 115 | * <pre><code> |
---|
| 116 | // modify the url for the action |
---|
| 117 | myStore.on({ |
---|
| 118 | beforeload: { |
---|
| 119 | fn: function (store, options) { |
---|
| 120 | // use <tt>{@link Ext.data.HttpProxy#setUrl setUrl}</tt> to change the URL for *just* this request. |
---|
| 121 | store.proxy.setUrl('changed1.php'); |
---|
| 122 | |
---|
| 123 | // set optional second parameter to true to make this URL change |
---|
| 124 | // permanent, applying this URL for all subsequent requests. |
---|
| 125 | store.proxy.setUrl('changed1.php', true); |
---|
| 126 | |
---|
| 127 | // Altering the proxy API should be done using the public |
---|
| 128 | // method <tt>{@link Ext.data.DataProxy#setApi setApi}</tt>. |
---|
| 129 | store.proxy.setApi('read', 'changed2.php'); |
---|
| 130 | |
---|
| 131 | // Or set the entire API with a config-object. |
---|
| 132 | // When using the config-object option, you must redefine the <b>entire</b> |
---|
| 133 | // API -- not just a specific action of it. |
---|
| 134 | store.proxy.setApi({ |
---|
| 135 | read : 'changed_read.php', |
---|
| 136 | create : 'changed_create.php', |
---|
| 137 | update : 'changed_update.php', |
---|
| 138 | destroy : 'changed_destroy.php' |
---|
| 139 | }); |
---|
| 140 | } |
---|
| 141 | } |
---|
| 142 | }); |
---|
| 143 | * </code></pre> |
---|
| 144 | * </p> |
---|
| 145 | */ |
---|
| 146 | |
---|
| 147 | this.addEvents( |
---|
| 148 | /** |
---|
| 149 | * @event exception |
---|
| 150 | * <p>Fires if an exception occurs in the Proxy during a remote request. This event is relayed |
---|
| 151 | * through a corresponding {@link Ext.data.Store}.{@link Ext.data.Store#exception exception}, |
---|
| 152 | * so any Store instance may observe this event.</p> |
---|
| 153 | * <p>In addition to being fired through the DataProxy instance that raised the event, this event is also fired |
---|
| 154 | * through the Ext.data.DataProxy <i>class</i> to allow for centralized processing of exception events from <b>all</b> |
---|
| 155 | * DataProxies by attaching a listener to the Ext.data.DataProxy class itself.</p> |
---|
| 156 | * <p>This event can be fired for one of two reasons:</p> |
---|
| 157 | * <div class="mdetail-params"><ul> |
---|
| 158 | * <li>remote-request <b>failed</b> : <div class="sub-desc"> |
---|
| 159 | * The server did not return status === 200. |
---|
| 160 | * </div></li> |
---|
| 161 | * <li>remote-request <b>succeeded</b> : <div class="sub-desc"> |
---|
| 162 | * The remote-request succeeded but the reader could not read the response. |
---|
| 163 | * This means the server returned data, but the configured Reader threw an |
---|
| 164 | * error while reading the response. In this case, this event will be |
---|
| 165 | * raised and the caught error will be passed along into this event. |
---|
| 166 | * </div></li> |
---|
| 167 | * </ul></div> |
---|
| 168 | * <br><p>This event fires with two different contexts based upon the 2nd |
---|
| 169 | * parameter <tt>type [remote|response]</tt>. The first four parameters |
---|
| 170 | * are identical between the two contexts -- only the final two parameters |
---|
| 171 | * differ.</p> |
---|
| 172 | * @param {DataProxy} this The proxy that sent the request |
---|
| 173 | * @param {String} type |
---|
| 174 | * <p>The value of this parameter will be either <tt>'response'</tt> or <tt>'remote'</tt>.</p> |
---|
| 175 | * <div class="mdetail-params"><ul> |
---|
| 176 | * <li><b><tt>'response'</tt></b> : <div class="sub-desc"> |
---|
| 177 | * <p>An <b>invalid</b> response from the server was returned: either 404, |
---|
| 178 | * 500 or the response meta-data does not match that defined in the DataReader |
---|
| 179 | * (e.g.: root, idProperty, successProperty).</p> |
---|
| 180 | * </div></li> |
---|
| 181 | * <li><b><tt>'remote'</tt></b> : <div class="sub-desc"> |
---|
| 182 | * <p>A <b>valid</b> response was returned from the server having |
---|
| 183 | * successProperty === false. This response might contain an error-message |
---|
| 184 | * sent from the server. For example, the user may have failed |
---|
| 185 | * authentication/authorization or a database validation error occurred.</p> |
---|
| 186 | * </div></li> |
---|
| 187 | * </ul></div> |
---|
| 188 | * @param {String} action Name of the action (see {@link Ext.data.Api#actions}. |
---|
| 189 | * @param {Object} options The options for the action that were specified in the {@link #request}. |
---|
| 190 | * @param {Object} response |
---|
| 191 | * <p>The value of this parameter depends on the value of the <code>type</code> parameter:</p> |
---|
| 192 | * <div class="mdetail-params"><ul> |
---|
| 193 | * <li><b><tt>'response'</tt></b> : <div class="sub-desc"> |
---|
| 194 | * <p>The raw browser response object (e.g.: XMLHttpRequest)</p> |
---|
| 195 | * </div></li> |
---|
| 196 | * <li><b><tt>'remote'</tt></b> : <div class="sub-desc"> |
---|
| 197 | * <p>The decoded response object sent from the server.</p> |
---|
| 198 | * </div></li> |
---|
| 199 | * </ul></div> |
---|
| 200 | * @param {Mixed} arg |
---|
| 201 | * <p>The type and value of this parameter depends on the value of the <code>type</code> parameter:</p> |
---|
| 202 | * <div class="mdetail-params"><ul> |
---|
| 203 | * <li><b><tt>'response'</tt></b> : Error<div class="sub-desc"> |
---|
| 204 | * <p>The JavaScript Error object caught if the configured Reader could not read the data. |
---|
| 205 | * If the remote request returns success===false, this parameter will be null.</p> |
---|
| 206 | * </div></li> |
---|
| 207 | * <li><b><tt>'remote'</tt></b> : Record/Record[]<div class="sub-desc"> |
---|
| 208 | * <p>This parameter will only exist if the <tt>action</tt> was a <b>write</b> action |
---|
| 209 | * (Ext.data.Api.actions.create|update|destroy).</p> |
---|
| 210 | * </div></li> |
---|
| 211 | * </ul></div> |
---|
| 212 | */ |
---|
| 213 | 'exception', |
---|
| 214 | /** |
---|
| 215 | * @event beforeload |
---|
| 216 | * Fires before a request to retrieve a data object. |
---|
| 217 | * @param {DataProxy} this The proxy for the request |
---|
| 218 | * @param {Object} params The params object passed to the {@link #request} function |
---|
| 219 | */ |
---|
| 220 | 'beforeload', |
---|
| 221 | /** |
---|
| 222 | * @event load |
---|
| 223 | * Fires before the load method's callback is called. |
---|
| 224 | * @param {DataProxy} this The proxy for the request |
---|
| 225 | * @param {Object} o The request transaction object |
---|
| 226 | * @param {Object} options The callback's <tt>options</tt> property as passed to the {@link #request} function |
---|
| 227 | */ |
---|
| 228 | 'load', |
---|
| 229 | /** |
---|
| 230 | * @event loadexception |
---|
| 231 | * <p>This event is <b>deprecated</b>. The signature of the loadexception event |
---|
| 232 | * varies depending on the proxy, use the catch-all {@link #exception} event instead. |
---|
| 233 | * This event will fire in addition to the {@link #exception} event.</p> |
---|
| 234 | * @param {misc} misc See {@link #exception}. |
---|
| 235 | * @deprecated |
---|
| 236 | */ |
---|
| 237 | 'loadexception', |
---|
| 238 | /** |
---|
| 239 | * @event beforewrite |
---|
| 240 | * <p>Fires before a request is generated for one of the actions Ext.data.Api.actions.create|update|destroy</p> |
---|
| 241 | * <p>In addition to being fired through the DataProxy instance that raised the event, this event is also fired |
---|
| 242 | * through the Ext.data.DataProxy <i>class</i> to allow for centralized processing of beforewrite events from <b>all</b> |
---|
| 243 | * DataProxies by attaching a listener to the Ext.data.DataProxy class itself.</p> |
---|
| 244 | * @param {DataProxy} this The proxy for the request |
---|
| 245 | * @param {String} action [Ext.data.Api.actions.create|update|destroy] |
---|
| 246 | * @param {Record/Record[]} rs The Record(s) to create|update|destroy. |
---|
| 247 | * @param {Object} params The request <code>params</code> object. Edit <code>params</code> to add parameters to the request. |
---|
| 248 | */ |
---|
| 249 | 'beforewrite', |
---|
| 250 | /** |
---|
| 251 | * @event write |
---|
| 252 | * <p>Fires before the request-callback is called</p> |
---|
| 253 | * <p>In addition to being fired through the DataProxy instance that raised the event, this event is also fired |
---|
| 254 | * through the Ext.data.DataProxy <i>class</i> to allow for centralized processing of write events from <b>all</b> |
---|
| 255 | * DataProxies by attaching a listener to the Ext.data.DataProxy class itself.</p> |
---|
| 256 | * @param {DataProxy} this The proxy that sent the request |
---|
| 257 | * @param {String} action [Ext.data.Api.actions.create|upate|destroy] |
---|
| 258 | * @param {Object} data The data object extracted from the server-response |
---|
| 259 | * @param {Object} response The decoded response from server |
---|
| 260 | * @param {Record/Record[]} rs The Record(s) from Store |
---|
| 261 | * @param {Object} options The callback's <tt>options</tt> property as passed to the {@link #request} function |
---|
| 262 | */ |
---|
| 263 | 'write' |
---|
| 264 | ); |
---|
| 265 | Ext.data.DataProxy.superclass.constructor.call(this); |
---|
| 266 | |
---|
| 267 | // Prepare the proxy api. Ensures all API-actions are defined with the Object-form. |
---|
| 268 | try { |
---|
| 269 | Ext.data.Api.prepare(this); |
---|
| 270 | } catch (e) { |
---|
| 271 | if (e instanceof Ext.data.Api.Error) { |
---|
| 272 | e.toConsole(); |
---|
| 273 | } |
---|
| 274 | } |
---|
| 275 | // relay each proxy's events onto Ext.data.DataProxy class for centralized Proxy-listening |
---|
| 276 | Ext.data.DataProxy.relayEvents(this, ['beforewrite', 'write', 'exception']); |
---|
| 277 | }; |
---|
| 278 | |
---|
| 279 | Ext.extend(Ext.data.DataProxy, Ext.util.Observable, { |
---|
| 280 | /** |
---|
| 281 | * @cfg {Boolean} restful |
---|
| 282 | * <p>Defaults to <tt>false</tt>. Set to <tt>true</tt> to operate in a RESTful manner.</p> |
---|
| 283 | * <br><p> Note: this parameter will automatically be set to <tt>true</tt> if the |
---|
| 284 | * {@link Ext.data.Store} it is plugged into is set to <code>restful: true</code>. If the |
---|
| 285 | * Store is RESTful, there is no need to set this option on the proxy.</p> |
---|
| 286 | * <br><p>RESTful implementations enable the serverside framework to automatically route |
---|
| 287 | * actions sent to one url based upon the HTTP method, for example: |
---|
| 288 | * <pre><code> |
---|
| 289 | store: new Ext.data.Store({ |
---|
| 290 | restful: true, |
---|
| 291 | proxy: new Ext.data.HttpProxy({url:'/users'}); // all requests sent to /users |
---|
| 292 | ... |
---|
| 293 | )} |
---|
| 294 | * </code></pre> |
---|
| 295 | * If there is no <code>{@link #api}</code> specified in the configuration of the proxy, |
---|
| 296 | * all requests will be marshalled to a single RESTful url (/users) so the serverside |
---|
| 297 | * framework can inspect the HTTP Method and act accordingly: |
---|
| 298 | * <pre> |
---|
| 299 | <u>Method</u> <u>url</u> <u>action</u> |
---|
| 300 | POST /users create |
---|
| 301 | GET /users read |
---|
| 302 | PUT /users/23 update |
---|
| 303 | DESTROY /users/23 delete |
---|
| 304 | * </pre></p> |
---|
| 305 | * <p>If set to <tt>true</tt>, a {@link Ext.data.Record#phantom non-phantom} record's |
---|
| 306 | * {@link Ext.data.Record#id id} will be appended to the url. Some MVC (e.g., Ruby on Rails, |
---|
| 307 | * Merb and Django) support segment based urls where the segments in the URL follow the |
---|
| 308 | * Model-View-Controller approach:<pre><code> |
---|
| 309 | * someSite.com/controller/action/id |
---|
| 310 | * </code></pre> |
---|
| 311 | * Where the segments in the url are typically:<div class="mdetail-params"><ul> |
---|
| 312 | * <li>The first segment : represents the controller class that should be invoked.</li> |
---|
| 313 | * <li>The second segment : represents the class function, or method, that should be called.</li> |
---|
| 314 | * <li>The third segment : represents the ID (a variable typically passed to the method).</li> |
---|
| 315 | * </ul></div></p> |
---|
| 316 | * <br><p>Refer to <code>{@link Ext.data.DataProxy#api}</code> for additional information.</p> |
---|
| 317 | */ |
---|
| 318 | restful: false, |
---|
| 319 | |
---|
| 320 | /** |
---|
| 321 | * <p>Redefines the Proxy's API or a single action of an API. Can be called with two method signatures.</p> |
---|
| 322 | * <p>If called with an object as the only parameter, the object should redefine the <b>entire</b> API, e.g.:</p><pre><code> |
---|
| 323 | proxy.setApi({ |
---|
| 324 | read : '/users/read', |
---|
| 325 | create : '/users/create', |
---|
| 326 | update : '/users/update', |
---|
| 327 | destroy : '/users/destroy' |
---|
| 328 | }); |
---|
| 329 | </code></pre> |
---|
| 330 | * <p>If called with two parameters, the first parameter should be a string specifying the API action to |
---|
| 331 | * redefine and the second parameter should be the URL (or function if using DirectProxy) to call for that action, e.g.:</p><pre><code> |
---|
| 332 | proxy.setApi(Ext.data.Api.actions.read, '/users/new_load_url'); |
---|
| 333 | </code></pre> |
---|
| 334 | * @param {String/Object} api An API specification object, or the name of an action. |
---|
| 335 | * @param {String/Function} url The URL (or function if using DirectProxy) to call for the action. |
---|
| 336 | */ |
---|
| 337 | setApi : function() { |
---|
| 338 | if (arguments.length == 1) { |
---|
| 339 | var valid = Ext.data.Api.isValid(arguments[0]); |
---|
| 340 | if (valid === true) { |
---|
| 341 | this.api = arguments[0]; |
---|
| 342 | } |
---|
| 343 | else { |
---|
| 344 | throw new Ext.data.Api.Error('invalid', valid); |
---|
| 345 | } |
---|
| 346 | } |
---|
| 347 | else if (arguments.length == 2) { |
---|
| 348 | if (!Ext.data.Api.isAction(arguments[0])) { |
---|
| 349 | throw new Ext.data.Api.Error('invalid', arguments[0]); |
---|
| 350 | } |
---|
| 351 | this.api[arguments[0]] = arguments[1]; |
---|
| 352 | } |
---|
| 353 | Ext.data.Api.prepare(this); |
---|
| 354 | }, |
---|
| 355 | |
---|
| 356 | /** |
---|
| 357 | * Returns true if the specified action is defined as a unique action in the api-config. |
---|
| 358 | * request. If all API-actions are routed to unique urls, the xaction parameter is unecessary. However, if no api is defined |
---|
| 359 | * and all Proxy actions are routed to DataProxy#url, the server-side will require the xaction parameter to perform a switch to |
---|
| 360 | * the corresponding code for CRUD action. |
---|
| 361 | * @param {String [Ext.data.Api.CREATE|READ|UPDATE|DESTROY]} action |
---|
| 362 | * @return {Boolean} |
---|
| 363 | */ |
---|
| 364 | isApiAction : function(action) { |
---|
| 365 | return (this.api[action]) ? true : false; |
---|
| 366 | }, |
---|
| 367 | |
---|
| 368 | /** |
---|
| 369 | * All proxy actions are executed through this method. Automatically fires the "before" + action event |
---|
| 370 | * @param {String} action Name of the action |
---|
| 371 | * @param {Ext.data.Record/Ext.data.Record[]/null} rs Will be null when action is 'load' |
---|
| 372 | * @param {Object} params |
---|
| 373 | * @param {Ext.data.DataReader} reader |
---|
| 374 | * @param {Function} callback |
---|
| 375 | * @param {Object} scope The scope (<code>this</code> reference) in which the callback function is executed. Defaults to the Proxy object. |
---|
| 376 | * @param {Object} options Any options specified for the action (e.g. see {@link Ext.data.Store#load}. |
---|
| 377 | */ |
---|
| 378 | request : function(action, rs, params, reader, callback, scope, options) { |
---|
| 379 | if (!this.api[action] && !this.load) { |
---|
| 380 | throw new Ext.data.DataProxy.Error('action-undefined', action); |
---|
| 381 | } |
---|
| 382 | params = params || {}; |
---|
| 383 | if ((action === Ext.data.Api.actions.read) ? this.fireEvent("beforeload", this, params) : this.fireEvent("beforewrite", this, action, rs, params) !== false) { |
---|
| 384 | this.doRequest.apply(this, arguments); |
---|
| 385 | } |
---|
| 386 | else { |
---|
| 387 | callback.call(scope || this, null, options, false); |
---|
| 388 | } |
---|
| 389 | }, |
---|
| 390 | |
---|
| 391 | |
---|
| 392 | /** |
---|
| 393 | * <b>Deprecated</b> load method using old method signature. See {@doRequest} for preferred method. |
---|
| 394 | * @deprecated |
---|
| 395 | * @param {Object} params |
---|
| 396 | * @param {Object} reader |
---|
| 397 | * @param {Object} callback |
---|
| 398 | * @param {Object} scope |
---|
| 399 | * @param {Object} arg |
---|
| 400 | */ |
---|
| 401 | load : null, |
---|
| 402 | |
---|
| 403 | /** |
---|
| 404 | * @cfg {Function} doRequest Abstract method that should be implemented in all subclasses. <b>Note:</b> Should only be used by custom-proxy developers. |
---|
| 405 | * (e.g.: {@link Ext.data.HttpProxy#doRequest HttpProxy.doRequest}, |
---|
| 406 | * {@link Ext.data.DirectProxy#doRequest DirectProxy.doRequest}). |
---|
| 407 | */ |
---|
| 408 | doRequest : function(action, rs, params, reader, callback, scope, options) { |
---|
| 409 | // default implementation of doRequest for backwards compatibility with 2.0 proxies. |
---|
| 410 | // If we're executing here, the action is probably "load". |
---|
| 411 | // Call with the pre-3.0 method signature. |
---|
| 412 | this.load(params, reader, callback, scope, options); |
---|
| 413 | }, |
---|
| 414 | |
---|
| 415 | /** |
---|
| 416 | * @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}. |
---|
| 417 | * @param {String} action Action name as per {@link Ext.data.Api.actions#read}. |
---|
| 418 | * @param {Object} o The request transaction object |
---|
| 419 | * @param {Object} res The server response |
---|
| 420 | * @fires loadexception (deprecated) |
---|
| 421 | * @fires exception |
---|
| 422 | * @fires load |
---|
| 423 | * @protected |
---|
| 424 | */ |
---|
| 425 | onRead : Ext.emptyFn, |
---|
| 426 | /** |
---|
| 427 | * @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}. |
---|
| 428 | * @param {String} action [Ext.data.Api.actions.create|read|update|destroy] |
---|
| 429 | * @param {Object} trans The request transaction object |
---|
| 430 | * @param {Object} res The server response |
---|
| 431 | * @fires exception |
---|
| 432 | * @fires write |
---|
| 433 | * @protected |
---|
| 434 | */ |
---|
| 435 | onWrite : Ext.emptyFn, |
---|
| 436 | /** |
---|
| 437 | * buildUrl |
---|
| 438 | * Sets the appropriate url based upon the action being executed. If restful is true, and only a single record is being acted upon, |
---|
| 439 | * url will be built Rails-style, as in "/controller/action/32". restful will aply iff the supplied record is an |
---|
| 440 | * instance of Ext.data.Record rather than an Array of them. |
---|
| 441 | * @param {String} action The api action being executed [read|create|update|destroy] |
---|
| 442 | * @param {Ext.data.Record/Ext.data.Record[]} record The record or Array of Records being acted upon. |
---|
| 443 | * @return {String} url |
---|
| 444 | * @private |
---|
| 445 | */ |
---|
| 446 | buildUrl : function(action, record) { |
---|
| 447 | record = record || null; |
---|
| 448 | |
---|
| 449 | // conn.url gets nullified after each request. If it's NOT null here, that means the user must have intervened with a call |
---|
| 450 | // to DataProxy#setUrl or DataProxy#setApi and changed it before the request was executed. If that's the case, use conn.url, |
---|
| 451 | // otherwise, build the url from the api or this.url. |
---|
| 452 | var url = (this.conn && this.conn.url) ? this.conn.url : (this.api[action]) ? this.api[action].url : this.url; |
---|
| 453 | if (!url) { |
---|
| 454 | throw new Ext.data.Api.Error('invalid-url', action); |
---|
| 455 | } |
---|
| 456 | |
---|
| 457 | // look for urls having "provides" suffix used in some MVC frameworks like Rails/Merb and others. The provides suffice informs |
---|
| 458 | // the server what data-format the client is dealing with and returns data in the same format (eg: application/json, application/xml, etc) |
---|
| 459 | // e.g.: /users.json, /users.xml, etc. |
---|
| 460 | // with restful routes, we need urls like: |
---|
| 461 | // PUT /users/1.json |
---|
| 462 | // DELETE /users/1.json |
---|
| 463 | var provides = null; |
---|
| 464 | var m = url.match(/(.*)(\.json|\.xml|\.html)$/); |
---|
| 465 | if (m) { |
---|
| 466 | provides = m[2]; // eg ".json" |
---|
| 467 | url = m[1]; // eg: "/users" |
---|
| 468 | } |
---|
| 469 | // prettyUrls is deprectated in favor of restful-config |
---|
| 470 | if ((this.restful === true || this.prettyUrls === true) && record instanceof Ext.data.Record && !record.phantom) { |
---|
| 471 | url += '/' + record.id; |
---|
| 472 | } |
---|
| 473 | return (provides === null) ? url : url + provides; |
---|
| 474 | }, |
---|
| 475 | |
---|
| 476 | /** |
---|
| 477 | * Destroys the proxy by purging any event listeners and cancelling any active requests. |
---|
| 478 | */ |
---|
| 479 | destroy: function(){ |
---|
| 480 | this.purgeListeners(); |
---|
| 481 | } |
---|
| 482 | }); |
---|
| 483 | |
---|
| 484 | // Apply the Observable prototype to the DataProxy class so that proxy instances can relay their |
---|
| 485 | // events to the class. Allows for centralized listening of all proxy instances upon the DataProxy class. |
---|
| 486 | Ext.apply(Ext.data.DataProxy, Ext.util.Observable.prototype); |
---|
| 487 | Ext.util.Observable.call(Ext.data.DataProxy); |
---|
| 488 | |
---|
| 489 | /** |
---|
| 490 | * @class Ext.data.DataProxy.Error |
---|
| 491 | * @extends Ext.Error |
---|
| 492 | * DataProxy Error extension. |
---|
| 493 | * constructor |
---|
| 494 | * @param {String} message Message describing the error. |
---|
| 495 | * @param {Record/Record[]} arg |
---|
| 496 | */ |
---|
| 497 | Ext.data.DataProxy.Error = Ext.extend(Ext.Error, { |
---|
| 498 | constructor : function(message, arg) { |
---|
| 499 | this.arg = arg; |
---|
| 500 | Ext.Error.call(this, message); |
---|
| 501 | }, |
---|
| 502 | name: 'Ext.data.DataProxy' |
---|
| 503 | }); |
---|
| 504 | Ext.apply(Ext.data.DataProxy.Error.prototype, { |
---|
| 505 | lang: { |
---|
| 506 | 'action-undefined': "DataProxy attempted to execute an API-action but found an undefined url / function. Please review your Proxy url/api-configuration.", |
---|
| 507 | 'api-invalid': 'Recieved an invalid API-configuration. Please ensure your proxy API-configuration contains only the actions from Ext.data.Api.actions.' |
---|
| 508 | } |
---|
| 509 | }); |
---|
| 510 | |
---|
| 511 | |
---|