Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / src / data / proxy / Direct.js
1 /*
2
3 This file is part of Ext JS 4
4
5 Copyright (c) 2011 Sencha Inc
6
7 Contact:  http://www.sencha.com/contact
8
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
11
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13
14 */
15 /**
16  * This class is used to send requests to the server using {@link Ext.direct.Manager Ext.Direct}. When a
17  * request is made, the transport mechanism is handed off to the appropriate
18  * {@link Ext.direct.RemotingProvider Provider} to complete the call.
19  *
20  * # Specifying the function
21  *
22  * This proxy expects a Direct remoting method to be passed in order to be able to complete requests.
23  * This can be done by specifying the {@link #directFn} configuration. This will use the same direct
24  * method for all requests. Alternatively, you can provide an {@link #api} configuration. This
25  * allows you to specify a different remoting method for each CRUD action.
26  *
27  * # Parameters
28  *
29  * This proxy provides options to help configure which parameters will be sent to the server.
30  * By specifying the {@link #paramsAsHash} option, it will send an object literal containing each
31  * of the passed parameters. The {@link #paramOrder} option can be used to specify the order in which
32  * the remoting method parameters are passed.
33  *
34  * # Example Usage
35  *
36  *     Ext.define('User', {
37  *         extend: 'Ext.data.Model',
38  *         fields: ['firstName', 'lastName'],
39  *         proxy: {
40  *             type: 'direct',
41  *             directFn: MyApp.getUsers,
42  *             paramOrder: 'id' // Tells the proxy to pass the id as the first parameter to the remoting method.
43  *         }
44  *     });
45  *     User.load(1);
46  */
47 Ext.define('Ext.data.proxy.Direct', {
48     /* Begin Definitions */
49
50     extend: 'Ext.data.proxy.Server',
51     alternateClassName: 'Ext.data.DirectProxy',
52
53     alias: 'proxy.direct',
54
55     requires: ['Ext.direct.Manager'],
56
57     /* End Definitions */
58
59     /**
60      * @cfg {String/String[]} paramOrder
61      * Defaults to undefined. A list of params to be executed server side.  Specify the params in the order in
62      * which they must be executed on the server-side as either (1) an Array of String values, or (2) a String
63      * of params delimited by either whitespace, comma, or pipe. For example, any of the following would be
64      * acceptable:
65      *
66      *     paramOrder: ['param1','param2','param3']
67      *     paramOrder: 'param1 param2 param3'
68      *     paramOrder: 'param1,param2,param3'
69      *     paramOrder: 'param1|param2|param'
70      */
71     paramOrder: undefined,
72
73     /**
74      * @cfg {Boolean} paramsAsHash
75      * Send parameters as a collection of named arguments.
76      * Providing a {@link #paramOrder} nullifies this configuration.
77      */
78     paramsAsHash: true,
79
80     /**
81      * @cfg {Function} directFn
82      * Function to call when executing a request.  directFn is a simple alternative to defining the api configuration-parameter
83      * for Store's which will not implement a full CRUD api.
84      */
85     directFn : undefined,
86
87     /**
88      * @cfg {Object} api
89      * The same as {@link Ext.data.proxy.Server#api}, however instead of providing urls, you should provide a direct
90      * function call.
91      */
92
93     /**
94      * @cfg {Object} extraParams
95      * Extra parameters that will be included on every read request. Individual requests with params
96      * of the same name will override these params when they are in conflict.
97      */
98
99     // private
100     paramOrderRe: /[\s,|]/,
101
102     constructor: function(config){
103         var me = this;
104
105         Ext.apply(me, config);
106         if (Ext.isString(me.paramOrder)) {
107             me.paramOrder = me.paramOrder.split(me.paramOrderRe);
108         }
109         me.callParent(arguments);
110     },
111
112     doRequest: function(operation, callback, scope) {
113         var me = this,
114             writer = me.getWriter(),
115             request = me.buildRequest(operation, callback, scope),
116             fn = me.api[request.action]  || me.directFn,
117             args = [],
118             params = request.params,
119             paramOrder = me.paramOrder,
120             method,
121             i = 0,
122             len;
123
124         //<debug>
125         if (!fn) {
126             Ext.Error.raise('No direct function specified for this proxy');
127         }
128         //</debug>
129
130         if (operation.allowWrite()) {
131             request = writer.write(request);
132         }
133
134         if (operation.action == 'read') {
135             // We need to pass params
136             method = fn.directCfg.method;
137
138             if (method.ordered) {
139                 if (method.len > 0) {
140                     if (paramOrder) {
141                         for (len = paramOrder.length; i < len; ++i) {
142                             args.push(params[paramOrder[i]]);
143                         }
144                     } else if (me.paramsAsHash) {
145                         args.push(params);
146                     }
147                 }
148             } else {
149                 args.push(params);
150             }
151         } else {
152             args.push(request.jsonData);
153         }
154
155         Ext.apply(request, {
156             args: args,
157             directFn: fn
158         });
159         args.push(me.createRequestCallback(request, operation, callback, scope), me);
160         fn.apply(window, args);
161     },
162
163     /*
164      * Inherit docs. We don't apply any encoding here because
165      * all of the direct requests go out as jsonData
166      */
167     applyEncoding: function(value){
168         return value;
169     },
170
171     createRequestCallback: function(request, operation, callback, scope){
172         var me = this;
173
174         return function(data, event){
175             me.processResponse(event.status, operation, request, event, callback, scope);
176         };
177     },
178
179     // inherit docs
180     extractResponseData: function(response){
181         return Ext.isDefined(response.result) ? response.result : response.data;
182     },
183
184     // inherit docs
185     setException: function(operation, response) {
186         operation.setException(response.message);
187     },
188
189     // inherit docs
190     buildUrl: function(){
191         return '';
192     }
193 });
194