Skip to content

Commit

Permalink
Rafactored DwrProxy so that it mirrors Ext.data.HttpProxy. The load h…
Browse files Browse the repository at this point in the history
…as been removed. This is a first step to make it easier to support additional CRUD methods, and to make one understand the proxy code easier as it's now more similar to Ext 3.x's proxies.

The upgrade guide was also updated noting to not use the loadexception event or the load method as they have both been deprecated in Ext 3.x.
  • Loading branch information
BigLep committed Jun 15, 2009
1 parent 9a26ac6 commit 11caab0
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 62 deletions.
8 changes: 7 additions & 1 deletion UPGRADE.markdown
Expand Up @@ -24,4 +24,10 @@ Upgrading to the Ext 3.x compatible version of Ext.ux.data.DwrProxy involves the
}
});

Adopting Ext's "api" syntax makes adding support for additional CRUD operations in the future easier.
Adopting Ext's "api" syntax makes adding support for additional CRUD operations in the future easier.

4. (optional) Remove listeners of the "loadexception" event as this event has been deprecated in Ext 3.x.
Instead, listen to the "exception" event.

5. (optional) Remove invocations of the "load" method as it has been deprecated in Ext 3.x.
Instead, use the "request" method.
189 changes: 128 additions & 61 deletions source/data/DwrProxy.js
Expand Up @@ -9,23 +9,23 @@ Ext.namespace("Ext.ux.data");
* The following constructor sample code contains all the available options that can be set:
* <code><pre>
* new Ext.ux.data.DwrProxy({
* // Defined by Ext.data.DataProxy
* api : {
* read : DwrInterface.interfaceMethodName
* },
* // Defined by Ext.Observable
* listeners: {
* 'beforeload': function(dataProxy, params) {
* // DwrProxy knows to pull parameters for the Dwr call from params[dataProxy.loadArgsKey].
* params[dataProxy.loadArgsKey] = [
* // arg1 for DwrInterface.interfaceMethodName
* // arg2 for DwrInterface.interfaceMethodName
* // etc...
* ];
* }
* },
* // Defined by Ext.ux.data.DwrProxy
* loadArgsKey : 'newLoadArgsKey' // This configuration option should almost never need to be set
* // Defined by Ext.data.DataProxy
* api : {
* read : DwrInterface.interfaceMethodName
* },
* // Defined by Ext.Observable
* listeners: {
* 'beforeload': function(dataProxy, params) {
* // DwrProxy knows to pull parameters for the Dwr call from params[dataProxy.loadArgsKey].
* params[dataProxy.loadArgsKey] = [
* // arg1 for DwrInterface.interfaceMethodName
* // arg2 for DwrInterface.interfaceMethodName
* // etc...
* ];
* }
* },
* // Defined by Ext.ux.data.DwrProxy
* loadArgsKey : 'newLoadArgsKey' // This configuration option should almost never need to be set
* });
* </pre></code>
* Note that currently only the "read" operation is supported. Support for the rest of the CRUD options will be added soon.
Expand Down Expand Up @@ -56,60 +56,127 @@ Ext.extend(Ext.ux.data.DwrProxy, Ext.data.DataProxy, {
loadArgsKey: 'dwrFunctionArgs',

/**
* Load data from the configured "dwrFunction",
* read the data object into a block of Ext.data.Records using the passed {@link Ext.data.DataReader} implementation,
* and process that block using the passed callback.
* @param {Object} params An object containing properties which are to be used for the request to the remote server.
* DwrProxy implementation of DataProxy#doRequest.
* This implementation attempts to mirror HttpProxy#doRequest as much as possible.
* Requests are done using configured "DWR function" for the provided "action".
* In the "read" case, the response data object is read into a block of Ext.data.Records using the passed {@link Ext.data.DataReader},
* and the records are then passed using to the provided callback.
* @param {String} action The crud action type (create, read, update, destroy). Note: only "read" is currently supported.
* @param {Ext.data.Record/Ext.data.Record[]} records If action is "read", records will be null.
* @param {Object} params An object containing properties which are to be used as parameters for the request to the remote server.
* Params is an Object, but the "DWR function" needs to be called with arguments in order.
* To ensure that one's arguments are passed to their DWR function correctly, a user must either:
* 1. call or know that the load method was called explictly where the "params" argument's properties were added in the order expected by DWR OR
* 2. listen to the "beforeload" event and add a property to params defined by "loadArgsKey" that is an array of the arguments to pass on to DWR.
* 1. call or know that the execute method was called explictly where the "params" argument's properties were added in the order expected by DWR OR
* 2. listen to the "beforeload" and/or "beforewrite" events and add a property to params defined by "loadArgsKey" that is an array of the arguments to pass on to DWR.
* If there is no property as defined by "loadArgsKey" within "params", then the whole "params" object will be used as the "loadArgs".
* If there is a property as defined by "loadArgsKey" within "params", then this property will be used as the "loagArgs".
* The "loadArgs" are iterated over to build up the list of arguments to pass to the "dwrFunction".
* The "loadArgs" are iterated over to build up the list of arguments to pass to the "DWR function".
* @param {Ext.data.DataReader} reader The Reader object which converts the data object into a block of Ext.data.Records.
* @param {Function} callback The function into which to pass the block of Ext.data.Records.
* The function must be passed <ul>
* <li>The Record block object</li>
* <li>The "arg" argument from the load function</li>
* <li>A boolean success indicator</li>
* @param {Function} callback A function to be called after the request.
* The callback is passed the following arguments:<ul>
* <li>records: Ext.data.Record[] The block of Ext.data.Records handled by the request.</li>
* <li>params: The params object passed to this doRequest method</li>
* <li>success: Boolean success indicator</li>
* </ul>
* @param {Object} scope The scope in which to call the callback
* @param {Object} arg An optional argument which is passed to the callback as its second parameter.
* @param {Object} scope The scope in which to call the callback.
* @param {Object} options An optional argument which is passed to the callback as its second parameter.
* @private
*/
load: function(params, reader, loadCallback, scope, arg){
doRequest : function(action, records, params, reader, callback, callbackScope, options) {
var dataProxy = this;
if (dataProxy.fireEvent("beforeload", dataProxy, params) !== false) {
var loadArgs = params[this.loadArgsKey] || params; // the Array or Object to build up the "dwrFunctionArgs"
var dwrFunctionArgs = []; // the arguments that will be passed to the dwrFunction
if (loadArgs instanceof Array) {
// Note: can't do a foreach loop over arrays because Ext added the "remove" method to Array's prototype.
// This "remove" method gets added as an argument unless we explictly use numeric indexes.
for (var i = 0; i < loadArgs.length; i++) {
dwrFunctionArgs.push(loadArgs[i]);
}
} else { // loadArgs should be an Object
for (var loadArgName in loadArgs) {
dwrFunctionArgs.push(loadArgs[loadArgName]);
}
var loadArgs = params[this.loadArgsKey] || params; // the Array or Object to build up the "dwrFunctionArgs"
var dwrFunctionArgs = []; // the arguments that will be passed to the dwrFunction
if (loadArgs instanceof Array) {
// Note: can't do a foreach loop over arrays because Ext added the "remove" method to Array's prototype.
// This "remove" method gets added as an argument unless we explictly use numeric indexes.
for (var i = 0; i < loadArgs.length; i++) {
dwrFunctionArgs.push(loadArgs[i]);
}
dwrFunctionArgs.push({
callback: function(response){
// call readRecords verses read because read will attempt to decode the JSON,
// but as this point DWR has already decoded the JSON.
var records = reader.readRecords(response);
dataProxy.fireEvent("load", dataProxy, response, loadCallback);
loadCallback.call(scope, records, arg, true);
},
exceptionHandler: function(message, exception){
// the event is supposed to pass the response, but since DWR doesn't provide that to us, we pass the message.
dataProxy.fireEvent("loadexception", dataProxy, message, loadCallback, exception);
loadCallback.call(scope, null, arg, false);
} else { // loadArgs should be an Object
for (var loadArgName in loadArgs) {
dwrFunctionArgs.push(loadArgs[loadArgName]);
}
}
dwrFunctionArgs.push(this.createCallback(action, params, reader, callback, callbackScope, options));
this.api.read.apply(Object, dwrFunctionArgs); // the scope for calling the dwrFunction doesn't matter, so we simply set it to Object.
},

/**
* Helper method for doRequest which returns a callback function for a DWR request.
* The returned callback function in turn invokes the provided callback function.
* This mirrors HttpProxy#createCallsback.
* DWR is unique though in that it allows one to define a callback function for success and callback function for an exception.
* This exceptionHandler callback parallels Ext's "remote exception" case.
* This method thus returns two callback functions groupded as a single object that can be appended to the DWR function arguments as required by DWR.
* @param {String} action See doRequest#action.
* @param {Ext.data.Record/Ext.data.Record[]} records See doRequest#records.
* @param {Object} params See doRequest#params.
* @param {Ext.data.DataReader} reader See doRequest#reader.
* @param {Function} callback See doRequest#callback.
* @param {Object} scope See doRequest#scope.
* @param {Object} options See doRequest#options.
* @private
*/
createCallback : function(action, params, reader, callback, callbackScope, options) {
return {
callback: function(response){
if (action === Ext.data.Api.actions.read) {
this.onRead(action, params, reader, callback, callbackScope, options, response);
} else {
this.onWrite();
}
});
this.api.read.apply(Object, dwrFunctionArgs); // the scope for calling the dwrFunction doesn't matter, so we simply set it to Object.
} else { // the beforeload event was vetoed
callback.call(scope || this, null, arg, false);
}.createDelegate(this),
exceptionHandler : function(message, exception) {
if (action === Ext.data.Api.actions.read) {
// @deprecated: Fire loadexception for backwards compatibility.
// The event is supposed to pass the response, but since DWR doesn't provide that to us, we pass the message.
this.fireEvent("loadexception", this, params, message, exception);
}
// The event is supposed to pass the response, but since DWR doesn't provide that to us, we pass the message.
this.fireEvent("exception", this, 'remote', action, params, message, exception);
callback.call(callbackScope, null, options, false);
}.createDelegate(this)
};
},

/**
* Helper method for createCallback for handling the read action.
* After creating records from the provided response, it calls the provided callback function.
* This mirrors HttpProxy#onRead.
* @param {String} action See doRequest#action.
* @param {Ext.data.Record/Ext.data.Record[]} records See doRequest#records.
* @param {Object} params See doRequest#params.
* @param {Ext.data.DataReader} reader See doRequest#reader.
* @param {Function} callback See doRequest#callback.
* @param {Object} scope See doRequest#scope.
* @param {Object} options See doRequest#options.
* @param {Object} response The response from the DWR call. This should be an Object which can be converted to Ext.data.Records.
* @private
*/
onRead : function(action, params, reader, callback, callbackScope, options, response) {
var records;
try {
// Call readRecords verses read because read will attempt to decode the JSON,
// but as this point DWR has already decoded the JSON.
records = reader.readRecords(response);
} catch(e) {
// @deprecated: Fire loadexception for backwards compatibility.
this.fireEvent("loadexception", this, params, response, e);
this.fireEvent('exception', this, 'response', action, params, response, e);
callback.call(callbackScope, null, options, false);
return;
}
this.fireEvent("load", this, params, options);
callback.call(callbackScope, records, options, true);
},

/**
* Helper method for createCallback for handling the create, update, and delete actions.
* This mirrors HttpProxy#onWrite
* TODO: implement
* @private
*/
onWrite : function() {
throw new Exception('create, update, and delete actions are not implemented yet.')
}
});

0 comments on commit 11caab0

Please sign in to comment.