Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / source / Server.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-data-proxy-Server'>/**
19 </span> * @author Ed Spencer
20  *
21  * ServerProxy is a superclass of {@link Ext.data.proxy.JsonP JsonPProxy} and {@link Ext.data.proxy.Ajax AjaxProxy}, and
22  * would not usually be used directly.
23  *
24  * ServerProxy should ideally be named HttpProxy as it is a superclass for all HTTP proxies - for Ext JS 4.x it has been
25  * called ServerProxy to enable any 3.x applications that reference the HttpProxy to continue to work (HttpProxy is now
26  * an alias of AjaxProxy).
27  * @private
28  */
29 Ext.define('Ext.data.proxy.Server', {
30     extend: 'Ext.data.proxy.Proxy',
31     alias : 'proxy.server',
32     alternateClassName: 'Ext.data.ServerProxy',
33     uses  : ['Ext.data.Request'],
34
35 <span id='Ext-data-proxy-Server-cfg-url'>    /**
36 </span>     * @cfg {String} url
37      * The URL from which to request the data object.
38      */
39
40 <span id='Ext-data-proxy-Server-cfg-pageParam'>    /**
41 </span>     * @cfg {String} pageParam
42      * The name of the 'page' parameter to send in a request. Defaults to 'page'. Set this to undefined if you don't
43      * want to send a page parameter.
44      */
45     pageParam: 'page',
46
47 <span id='Ext-data-proxy-Server-cfg-startParam'>    /**
48 </span>     * @cfg {String} startParam
49      * The name of the 'start' parameter to send in a request. Defaults to 'start'. Set this to undefined if you don't
50      * want to send a start parameter.
51      */
52     startParam: 'start',
53
54 <span id='Ext-data-proxy-Server-cfg-limitParam'>    /**
55 </span>     * @cfg {String} limitParam
56      * The name of the 'limit' parameter to send in a request. Defaults to 'limit'. Set this to undefined if you don't
57      * want to send a limit parameter.
58      */
59     limitParam: 'limit',
60
61 <span id='Ext-data-proxy-Server-cfg-groupParam'>    /**
62 </span>     * @cfg {String} groupParam
63      * The name of the 'group' parameter to send in a request. Defaults to 'group'. Set this to undefined if you don't
64      * want to send a group parameter.
65      */
66     groupParam: 'group',
67
68 <span id='Ext-data-proxy-Server-cfg-sortParam'>    /**
69 </span>     * @cfg {String} sortParam
70      * The name of the 'sort' parameter to send in a request. Defaults to 'sort'. Set this to undefined if you don't
71      * want to send a sort parameter.
72      */
73     sortParam: 'sort',
74
75 <span id='Ext-data-proxy-Server-cfg-filterParam'>    /**
76 </span>     * @cfg {String} filterParam
77      * The name of the 'filter' parameter to send in a request. Defaults to 'filter'. Set this to undefined if you don't
78      * want to send a filter parameter.
79      */
80     filterParam: 'filter',
81
82 <span id='Ext-data-proxy-Server-cfg-directionParam'>    /**
83 </span>     * @cfg {String} directionParam
84      * The name of the direction parameter to send in a request. **This is only used when simpleSortMode is set to
85      * true.** Defaults to 'dir'.
86      */
87     directionParam: 'dir',
88
89 <span id='Ext-data-proxy-Server-cfg-simpleSortMode'>    /**
90 </span>     * @cfg {Boolean} simpleSortMode
91      * Enabling simpleSortMode in conjunction with remoteSort will only send one sort property and a direction when a
92      * remote sort is requested. The directionParam and sortParam will be sent with the property name and either 'ASC'
93      * or 'DESC'.
94      */
95     simpleSortMode: false,
96
97 <span id='Ext-data-proxy-Server-cfg-noCache'>    /**
98 </span>     * @cfg {Boolean} noCache
99      * Disable caching by adding a unique parameter name to the request. Set to false to allow caching. Defaults to true.
100      */
101     noCache : true,
102
103 <span id='Ext-data-proxy-Server-cfg-cacheString'>    /**
104 </span>     * @cfg {String} cacheString
105      * The name of the cache param added to the url when using noCache. Defaults to &quot;_dc&quot;.
106      */
107     cacheString: &quot;_dc&quot;,
108
109 <span id='Ext-data-proxy-Server-cfg-timeout'>    /**
110 </span>     * @cfg {Number} timeout
111      * The number of milliseconds to wait for a response. Defaults to 30000 milliseconds (30 seconds).
112      */
113     timeout : 30000,
114
115 <span id='Ext-data-proxy-Server-cfg-api'>    /**
116 </span>     * @cfg {Object} api
117      * Specific urls to call on CRUD action methods &quot;create&quot;, &quot;read&quot;, &quot;update&quot; and &quot;destroy&quot;. Defaults to:
118      *
119      *     api: {
120      *         create  : undefined,
121      *         read    : undefined,
122      *         update  : undefined,
123      *         destroy : undefined
124      *     }
125      *
126      * The url is built based upon the action being executed [create|read|update|destroy] using the commensurate
127      * {@link #api} property, or if undefined default to the configured
128      * {@link Ext.data.Store}.{@link Ext.data.proxy.Server#url url}.
129      *
130      * For example:
131      *
132      *     api: {
133      *         create  : '/controller/new',
134      *         read    : '/controller/load',
135      *         update  : '/controller/update',
136      *         destroy : '/controller/destroy_action'
137      *     }
138      *
139      * If the specific URL for a given CRUD action is undefined, the CRUD action request will be directed to the
140      * configured {@link Ext.data.proxy.Server#url url}.
141      */
142
143     constructor: function(config) {
144         var me = this;
145
146         config = config || {};
147         this.addEvents(
148 <span id='Ext-data-proxy-Server-event-exception'>            /**
149 </span>             * @event exception
150              * Fires when the server returns an exception
151              * @param {Ext.data.proxy.Proxy} this
152              * @param {Object} response The response from the AJAX request
153              * @param {Ext.data.Operation} operation The operation that triggered request
154              */
155             'exception'
156         );
157         me.callParent([config]);
158
159 <span id='Ext-data-proxy-Server-cfg-extraParams'>        /**
160 </span>         * @cfg {Object} extraParams
161          * Extra parameters that will be included on every request. Individual requests with params of the same name
162          * will override these params when they are in conflict.
163          */
164         me.extraParams = config.extraParams || {};
165
166         me.api = config.api || {};
167
168         //backwards compatibility, will be deprecated in 5.0
169         me.nocache = me.noCache;
170     },
171
172     //in a ServerProxy all four CRUD operations are executed in the same manner, so we delegate to doRequest in each case
173     create: function() {
174         return this.doRequest.apply(this, arguments);
175     },
176
177     read: function() {
178         return this.doRequest.apply(this, arguments);
179     },
180
181     update: function() {
182         return this.doRequest.apply(this, arguments);
183     },
184
185     destroy: function() {
186         return this.doRequest.apply(this, arguments);
187     },
188
189 <span id='Ext-data-proxy-Server-method-buildRequest'>    /**
190 </span>     * Creates and returns an Ext.data.Request object based on the options passed by the {@link Ext.data.Store Store}
191      * that this Proxy is attached to.
192      * @param {Ext.data.Operation} operation The {@link Ext.data.Operation Operation} object to execute
193      * @return {Ext.data.Request} The request object
194      */
195     buildRequest: function(operation) {
196         var params = Ext.applyIf(operation.params || {}, this.extraParams || {}),
197             request;
198
199         //copy any sorters, filters etc into the params so they can be sent over the wire
200         params = Ext.applyIf(params, this.getParams(operation));
201
202         if (operation.id &amp;&amp; !params.id) {
203             params.id = operation.id;
204         }
205
206         request = Ext.create('Ext.data.Request', {
207             params   : params,
208             action   : operation.action,
209             records  : operation.records,
210             operation: operation,
211             url      : operation.url
212         });
213
214         request.url = this.buildUrl(request);
215
216         /*
217          * Save the request on the Operation. Operations don't usually care about Request and Response data, but in the
218          * ServerProxy and any of its subclasses we add both request and response as they may be useful for further processing
219          */
220         operation.request = request;
221
222         return request;
223     },
224
225     // Should this be documented as protected method?
226     processResponse: function(success, operation, request, response, callback, scope){
227         var me = this,
228             reader,
229             result;
230
231         if (success === true) {
232             reader = me.getReader();
233             result = reader.read(me.extractResponseData(response));
234
235             if (result.success !== false) {
236                 //see comment in buildRequest for why we include the response object here
237                 Ext.apply(operation, {
238                     response: response,
239                     resultSet: result
240                 });
241
242                 operation.commitRecords(result.records);
243                 operation.setCompleted();
244                 operation.setSuccessful();
245             } else {
246                 operation.setException(result.message);
247                 me.fireEvent('exception', this, response, operation);
248             }
249         } else {
250             me.setException(operation, response);
251             me.fireEvent('exception', this, response, operation);
252         }
253
254         //this callback is the one that was passed to the 'read' or 'write' function above
255         if (typeof callback == 'function') {
256             callback.call(scope || me, operation);
257         }
258
259         me.afterRequest(request, success);
260     },
261
262 <span id='Ext-data-proxy-Server-method-setException'>    /**
263 </span>     * Sets up an exception on the operation
264      * @private
265      * @param {Ext.data.Operation} operation The operation
266      * @param {Object} response The response
267      */
268     setException: function(operation, response){
269         operation.setException({
270             status: response.status,
271             statusText: response.statusText
272         });
273     },
274
275 <span id='Ext-data-proxy-Server-method-extractResponseData'>    /**
276 </span>     * Template method to allow subclasses to specify how to get the response for the reader.
277      * @template
278      * @private
279      * @param {Object} response The server response
280      * @return {Object} The response data to be used by the reader
281      */
282     extractResponseData: function(response){
283         return response;
284     },
285
286 <span id='Ext-data-proxy-Server-method-applyEncoding'>    /**
287 </span>     * Encode any values being sent to the server. Can be overridden in subclasses.
288      * @private
289      * @param {Array} An array of sorters/filters.
290      * @return {Object} The encoded value
291      */
292     applyEncoding: function(value){
293         return Ext.encode(value);
294     },
295
296 <span id='Ext-data-proxy-Server-method-encodeSorters'>    /**
297 </span>     * Encodes the array of {@link Ext.util.Sorter} objects into a string to be sent in the request url. By default,
298      * this simply JSON-encodes the sorter data
299      * @param {Ext.util.Sorter[]} sorters The array of {@link Ext.util.Sorter Sorter} objects
300      * @return {String} The encoded sorters
301      */
302     encodeSorters: function(sorters) {
303         var min = [],
304             length = sorters.length,
305             i = 0;
306
307         for (; i &lt; length; i++) {
308             min[i] = {
309                 property : sorters[i].property,
310                 direction: sorters[i].direction
311             };
312         }
313         return this.applyEncoding(min);
314
315     },
316
317 <span id='Ext-data-proxy-Server-method-encodeFilters'>    /**
318 </span>     * Encodes the array of {@link Ext.util.Filter} objects into a string to be sent in the request url. By default,
319      * this simply JSON-encodes the filter data
320      * @param {Ext.util.Filter[]} filters The array of {@link Ext.util.Filter Filter} objects
321      * @return {String} The encoded filters
322      */
323     encodeFilters: function(filters) {
324         var min = [],
325             length = filters.length,
326             i = 0;
327
328         for (; i &lt; length; i++) {
329             min[i] = {
330                 property: filters[i].property,
331                 value   : filters[i].value
332             };
333         }
334         return this.applyEncoding(min);
335     },
336
337 <span id='Ext-data-proxy-Server-method-getParams'>    /**
338 </span>     * @private
339      * Copy any sorters, filters etc into the params so they can be sent over the wire
340      */
341     getParams: function(operation) {
342         var me             = this,
343             params         = {},
344             isDef          = Ext.isDefined,
345             groupers       = operation.groupers,
346             sorters        = operation.sorters,
347             filters        = operation.filters,
348             page           = operation.page,
349             start          = operation.start,
350             limit          = operation.limit,
351
352             simpleSortMode = me.simpleSortMode,
353
354             pageParam      = me.pageParam,
355             startParam     = me.startParam,
356             limitParam     = me.limitParam,
357             groupParam     = me.groupParam,
358             sortParam      = me.sortParam,
359             filterParam    = me.filterParam,
360             directionParam = me.directionParam;
361
362         if (pageParam &amp;&amp; isDef(page)) {
363             params[pageParam] = page;
364         }
365
366         if (startParam &amp;&amp; isDef(start)) {
367             params[startParam] = start;
368         }
369
370         if (limitParam &amp;&amp; isDef(limit)) {
371             params[limitParam] = limit;
372         }
373
374         if (groupParam &amp;&amp; groupers &amp;&amp; groupers.length &gt; 0) {
375             // Grouper is a subclass of sorter, so we can just use the sorter method
376             params[groupParam] = me.encodeSorters(groupers);
377         }
378
379         if (sortParam &amp;&amp; sorters &amp;&amp; sorters.length &gt; 0) {
380             if (simpleSortMode) {
381                 params[sortParam] = sorters[0].property;
382                 params[directionParam] = sorters[0].direction;
383             } else {
384                 params[sortParam] = me.encodeSorters(sorters);
385             }
386
387         }
388
389         if (filterParam &amp;&amp; filters &amp;&amp; filters.length &gt; 0) {
390             params[filterParam] = me.encodeFilters(filters);
391         }
392
393         return params;
394     },
395
396 <span id='Ext-data-proxy-Server-method-buildUrl'>    /**
397 </span>     * Generates a url based on a given Ext.data.Request object. By default, ServerProxy's buildUrl will add the
398      * cache-buster param to the end of the url. Subclasses may need to perform additional modifications to the url.
399      * @param {Ext.data.Request} request The request object
400      * @return {String} The url
401      */
402     buildUrl: function(request) {
403         var me = this,
404             url = me.getUrl(request);
405
406         //&lt;debug&gt;
407         if (!url) {
408             Ext.Error.raise(&quot;You are using a ServerProxy but have not supplied it with a url.&quot;);
409         }
410         //&lt;/debug&gt;
411
412         if (me.noCache) {
413             url = Ext.urlAppend(url, Ext.String.format(&quot;{0}={1}&quot;, me.cacheString, Ext.Date.now()));
414         }
415
416         return url;
417     },
418
419 <span id='Ext-data-proxy-Server-method-getUrl'>    /**
420 </span>     * Get the url for the request taking into account the order of priority,
421      * - The request
422      * - The api
423      * - The url
424      * @private
425      * @param {Ext.data.Request} request The request
426      * @return {String} The url
427      */
428     getUrl: function(request){
429         return request.url || this.api[request.action] || this.url;
430     },
431
432 <span id='Ext-data-proxy-Server-method-doRequest'>    /**
433 </span>     * In ServerProxy subclasses, the {@link #create}, {@link #read}, {@link #update} and {@link #destroy} methods all
434      * pass through to doRequest. Each ServerProxy subclass must implement the doRequest method - see {@link
435      * Ext.data.proxy.JsonP} and {@link Ext.data.proxy.Ajax} for examples. This method carries the same signature as
436      * each of the methods that delegate to it.
437      *
438      * @param {Ext.data.Operation} operation The Ext.data.Operation object
439      * @param {Function} callback The callback function to call when the Operation has completed
440      * @param {Object} scope The scope in which to execute the callback
441      */
442     doRequest: function(operation, callback, scope) {
443         //&lt;debug&gt;
444         Ext.Error.raise(&quot;The doRequest function has not been implemented on your Ext.data.proxy.Server subclass. See src/data/ServerProxy.js for details&quot;);
445         //&lt;/debug&gt;
446     },
447
448 <span id='Ext-data-proxy-Server-method-afterRequest'>    /**
449 </span>     * Optional callback function which can be used to clean up after a request has been completed.
450      * @param {Ext.data.Request} request The Request object
451      * @param {Boolean} success True if the request was successful
452      * @method
453      */
454     afterRequest: Ext.emptyFn,
455
456     onDestroy: function() {
457         Ext.destroy(this.reader, this.writer);
458     }
459 });
460 </pre>
461 </body>
462 </html>