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; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-data-proxy-Server'>/**
19 </span> * @author Ed Spencer
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.
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).
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'],
35 <span id='Ext-data-proxy-Server-cfg-url'> /**
36 </span> * @cfg {String} url
37 * The URL from which to request the data object.
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.
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.
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.
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.
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.
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.
80 filterParam: 'filter',
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'.
87 directionParam: 'dir',
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'
95 simpleSortMode: false,
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.
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 "_dc".
107 cacheString: "_dc",
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).
115 <span id='Ext-data-proxy-Server-cfg-api'> /**
116 </span> * @cfg {Object} api
117 * Specific urls to call on CRUD action methods "create", "read", "update" and "destroy". Defaults to:
120 * create : undefined,
122 * update : undefined,
123 * destroy : undefined
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}.
133 * create : '/controller/new',
134 * read : '/controller/load',
135 * update : '/controller/update',
136 * destroy : '/controller/destroy_action'
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}.
143 constructor: function(config) {
146 config = config || {};
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
157 me.callParent([config]);
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.
164 me.extraParams = config.extraParams || {};
166 me.api = config.api || {};
168 //backwards compatibility, will be deprecated in 5.0
169 me.nocache = me.noCache;
172 //in a ServerProxy all four CRUD operations are executed in the same manner, so we delegate to doRequest in each case
174 return this.doRequest.apply(this, arguments);
178 return this.doRequest.apply(this, arguments);
182 return this.doRequest.apply(this, arguments);
185 destroy: function() {
186 return this.doRequest.apply(this, arguments);
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
195 buildRequest: function(operation) {
196 var params = Ext.applyIf(operation.params || {}, this.extraParams || {}),
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));
202 if (operation.id && !params.id) {
203 params.id = operation.id;
206 request = Ext.create('Ext.data.Request', {
208 action : operation.action,
209 records : operation.records,
210 operation: operation,
214 request.url = this.buildUrl(request);
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
220 operation.request = request;
225 // Should this be documented as protected method?
226 processResponse: function(success, operation, request, response, callback, scope){
231 if (success === true) {
232 reader = me.getReader();
233 result = reader.read(me.extractResponseData(response));
235 if (result.success !== false) {
236 //see comment in buildRequest for why we include the response object here
237 Ext.apply(operation, {
242 operation.commitRecords(result.records);
243 operation.setCompleted();
244 operation.setSuccessful();
246 operation.setException(result.message);
247 me.fireEvent('exception', this, response, operation);
250 me.setException(operation, response);
251 me.fireEvent('exception', this, response, operation);
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);
259 me.afterRequest(request, success);
262 <span id='Ext-data-proxy-Server-method-setException'> /**
263 </span> * Sets up an exception on the operation
265 * @param {Ext.data.Operation} operation The operation
266 * @param {Object} response The response
268 setException: function(operation, response){
269 operation.setException({
270 status: response.status,
271 statusText: response.statusText
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.
279 * @param {Object} response The server response
280 * @return {Object} The response data to be used by the reader
282 extractResponseData: function(response){
286 <span id='Ext-data-proxy-Server-method-applyEncoding'> /**
287 </span> * Encode any values being sent to the server. Can be overridden in subclasses.
289 * @param {Array} An array of sorters/filters.
290 * @return {Object} The encoded value
292 applyEncoding: function(value){
293 return Ext.encode(value);
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
302 encodeSorters: function(sorters) {
304 length = sorters.length,
307 for (; i < length; i++) {
309 property : sorters[i].property,
310 direction: sorters[i].direction
313 return this.applyEncoding(min);
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
323 encodeFilters: function(filters) {
325 length = filters.length,
328 for (; i < length; i++) {
330 property: filters[i].property,
331 value : filters[i].value
334 return this.applyEncoding(min);
337 <span id='Ext-data-proxy-Server-method-getParams'> /**
339 * Copy any sorters, filters etc into the params so they can be sent over the wire
341 getParams: function(operation) {
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,
352 simpleSortMode = me.simpleSortMode,
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;
362 if (pageParam && isDef(page)) {
363 params[pageParam] = page;
366 if (startParam && isDef(start)) {
367 params[startParam] = start;
370 if (limitParam && isDef(limit)) {
371 params[limitParam] = limit;
374 if (groupParam && groupers && groupers.length > 0) {
375 // Grouper is a subclass of sorter, so we can just use the sorter method
376 params[groupParam] = me.encodeSorters(groupers);
379 if (sortParam && sorters && sorters.length > 0) {
380 if (simpleSortMode) {
381 params[sortParam] = sorters[0].property;
382 params[directionParam] = sorters[0].direction;
384 params[sortParam] = me.encodeSorters(sorters);
389 if (filterParam && filters && filters.length > 0) {
390 params[filterParam] = me.encodeFilters(filters);
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
402 buildUrl: function(request) {
404 url = me.getUrl(request);
408 Ext.Error.raise("You are using a ServerProxy but have not supplied it with a url.");
413 url = Ext.urlAppend(url, Ext.String.format("{0}={1}", me.cacheString, Ext.Date.now()));
419 <span id='Ext-data-proxy-Server-method-getUrl'> /**
420 </span> * Get the url for the request taking into account the order of priority,
425 * @param {Ext.data.Request} request The request
426 * @return {String} The url
428 getUrl: function(request){
429 return request.url || this.api[request.action] || this.url;
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.
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
442 doRequest: function(operation, callback, scope) {
444 Ext.Error.raise("The doRequest function has not been implemented on your Ext.data.proxy.Server subclass. See src/data/ServerProxy.js for details");
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
454 afterRequest: Ext.emptyFn,
456 onDestroy: function() {
457 Ext.destroy(this.reader, this.writer);