evan.leonard
27 Dec 2006, 7:46 AM
Hello Jack and All,
I am using the new Image Chooser example to learn about how to use the JsonView and UpdateManager classes to dynamically retrieve data.
Following the example seems pretty straight forward, however in my environment we use json-rpc-java on the server-side to process asyncronous requests. I am interested in trying to tie together the JsonView with the json-rpc-java backend.
I've attempted to do this by making a subclass of UpdateManager with an overriden update method, and a subclass of JsonView that uses this update manager. However, this seems to be more difficult as I anticipated because of the many places that the UpdateManager relies on the transaction being a YAHOO.util.Connect object.
Can you suggest a better insertion point into the View object at which to take control of the asyncronous request? It seems that it should be possible to do. The only differences at the interface level should be supplying a methodName instead of a url, and a param array instead of an object. The output of the async call would be a json object.
Below is the code for as far as I got before deciding to ask for help.
RpcUpdateManager.js:
/**
* @param {String/HTMLElement/YAHOO.ext.Element} el The element to update
* @param {Boolean} forceNew (optional) By default the constructor checks to see if the passed element already has an UpdateManager and if it does it returns the same instance. This will skip that check (useful for extending this class).
*/
RpcUpdateManager = function(el, forceNew)
{
RpcUpdateManager.superclass.constructor.call(this, el, forceNew);
}
YAHOO.extendX(RpcUpdateManager, YAHOO.ext.UpdateManager, {
update : function(methodName, params, callback)
{
if(this.beforeUpdate.fireDirect(this.el) !== false){
if(typeof methodName == 'object'){ // must be config object
var cfg = methodName;
methodName = cfg.method;
params = params || cfg.params;
callback = callback || cfg.callback;
if(callback && cfg.scope){
callback = callback.createDelegate(cfg.scope);
}
if(typeof cfg.nocache != 'undefined'){this.disableCaching = cfg.nocache};
if(typeof cfg.text != 'undefined'){this.indicatorText = '<div class="loading-indicator">'+cfg.text+'</div>'};
if(typeof cfg.scripts != 'undefined'){this.loadScripts = cfg.scripts};
if(typeof cfg.timeout != 'undefined'){this.timeout = cfg.timeout};
}
this.showLoading();
if(typeof params == 'function'){
params = params();
}
this.transaction = new RpcClient();
if(callback == null) callback = function(){};
var req = this.transaction.makeRequest.call(this.transaction, methodName, params, callback);
JSONRpcClient.async_requests.push(req);
JSONRpcClient.kick_async();
}
},
/**
* Returns true if an update is in progress
* @return {Boolean}
*/
isUpdating : function(){
if(this.transaction){
JSONRpcClient.num_req_active > 0;
}
return false;
}
});
RpcView.js:
RpcView = function(container, tpl, config)
{
// Force the update manager to be our own instance.
this.el = getEl(container, true);
this.el.updateManager = new RpcUpdateManager(this.el, this);
// Call the super's constructor
RpcView.superclass.constructor.call(this, container, tpl, config);
}
YAHOO.extendX(RpcView, YAHOO.ext.JsonView, {
/**
* Performs an async request, loading the JSON from the response. If params are specified it uses POST, otherwise it uses GET.
* @param {String/Function} methodName The url for this request or a function to call to get the url or a config object containing any of the following options:
* @param {Array/Function} params (optional) The parameters to pass to the method on the server
* @param {Function} callback (optional) The method to call with the results upon successful completion.
*
<pre><code>
view.load({
methodName: 'ObjectName.methodName',
params: {param1: 'foo', param2: 'bar'}, // or a URL encoded string
callback: yourFunction,
nocache: false,
text: 'Loading...',
timeout: 30,
scripts: false
});
</code></pre>
* The only required property is methodName. The optional properties nocache, text and scripts
* are shorthand for disableCaching, indicatorText and loadScripts and are used to set their associated property on this UpdateManager instance.
*/
load : function(methodName, params, callback){
var um = this.el.getUpdateManager();
um.update.apply(um, arguments);
},
render : function(el, response){
this.clearSelections();
this.el.update('');
var o;
try{
o = YAHOO.ext.util.JSON.decode(response.responseText);
if(this.jsonRoot){
o = eval('o.' + this.jsonRoot);
}
}catch(e){}
/**
* The current json data or null
*/
this.jsonData = o;
this.beforeRender();
this.refresh();
}
});
I am using the new Image Chooser example to learn about how to use the JsonView and UpdateManager classes to dynamically retrieve data.
Following the example seems pretty straight forward, however in my environment we use json-rpc-java on the server-side to process asyncronous requests. I am interested in trying to tie together the JsonView with the json-rpc-java backend.
I've attempted to do this by making a subclass of UpdateManager with an overriden update method, and a subclass of JsonView that uses this update manager. However, this seems to be more difficult as I anticipated because of the many places that the UpdateManager relies on the transaction being a YAHOO.util.Connect object.
Can you suggest a better insertion point into the View object at which to take control of the asyncronous request? It seems that it should be possible to do. The only differences at the interface level should be supplying a methodName instead of a url, and a param array instead of an object. The output of the async call would be a json object.
Below is the code for as far as I got before deciding to ask for help.
RpcUpdateManager.js:
/**
* @param {String/HTMLElement/YAHOO.ext.Element} el The element to update
* @param {Boolean} forceNew (optional) By default the constructor checks to see if the passed element already has an UpdateManager and if it does it returns the same instance. This will skip that check (useful for extending this class).
*/
RpcUpdateManager = function(el, forceNew)
{
RpcUpdateManager.superclass.constructor.call(this, el, forceNew);
}
YAHOO.extendX(RpcUpdateManager, YAHOO.ext.UpdateManager, {
update : function(methodName, params, callback)
{
if(this.beforeUpdate.fireDirect(this.el) !== false){
if(typeof methodName == 'object'){ // must be config object
var cfg = methodName;
methodName = cfg.method;
params = params || cfg.params;
callback = callback || cfg.callback;
if(callback && cfg.scope){
callback = callback.createDelegate(cfg.scope);
}
if(typeof cfg.nocache != 'undefined'){this.disableCaching = cfg.nocache};
if(typeof cfg.text != 'undefined'){this.indicatorText = '<div class="loading-indicator">'+cfg.text+'</div>'};
if(typeof cfg.scripts != 'undefined'){this.loadScripts = cfg.scripts};
if(typeof cfg.timeout != 'undefined'){this.timeout = cfg.timeout};
}
this.showLoading();
if(typeof params == 'function'){
params = params();
}
this.transaction = new RpcClient();
if(callback == null) callback = function(){};
var req = this.transaction.makeRequest.call(this.transaction, methodName, params, callback);
JSONRpcClient.async_requests.push(req);
JSONRpcClient.kick_async();
}
},
/**
* Returns true if an update is in progress
* @return {Boolean}
*/
isUpdating : function(){
if(this.transaction){
JSONRpcClient.num_req_active > 0;
}
return false;
}
});
RpcView.js:
RpcView = function(container, tpl, config)
{
// Force the update manager to be our own instance.
this.el = getEl(container, true);
this.el.updateManager = new RpcUpdateManager(this.el, this);
// Call the super's constructor
RpcView.superclass.constructor.call(this, container, tpl, config);
}
YAHOO.extendX(RpcView, YAHOO.ext.JsonView, {
/**
* Performs an async request, loading the JSON from the response. If params are specified it uses POST, otherwise it uses GET.
* @param {String/Function} methodName The url for this request or a function to call to get the url or a config object containing any of the following options:
* @param {Array/Function} params (optional) The parameters to pass to the method on the server
* @param {Function} callback (optional) The method to call with the results upon successful completion.
*
<pre><code>
view.load({
methodName: 'ObjectName.methodName',
params: {param1: 'foo', param2: 'bar'}, // or a URL encoded string
callback: yourFunction,
nocache: false,
text: 'Loading...',
timeout: 30,
scripts: false
});
</code></pre>
* The only required property is methodName. The optional properties nocache, text and scripts
* are shorthand for disableCaching, indicatorText and loadScripts and are used to set their associated property on this UpdateManager instance.
*/
load : function(methodName, params, callback){
var um = this.el.getUpdateManager();
um.update.apply(um, arguments);
},
render : function(el, response){
this.clearSelections();
this.el.update('');
var o;
try{
o = YAHOO.ext.util.JSON.decode(response.responseText);
if(this.jsonRoot){
o = eval('o.' + this.jsonRoot);
}
}catch(e){}
/**
* The current json data or null
*/
this.jsonData = o;
this.beforeRender();
this.refresh();
}
});