PDA

View Full Version : Stumped on extending DataProxy



joeloftus
5 Nov 2010, 8:57 AM
I'm trying to extend DataProxy so that it calls a js function with start/limit params instead of making an Ajax call. This proxy is used by a store that is used in a PagingToolbar. I'm having trouble understanding how to interact with the default DataProxy behavior to make a function call instead of an Ajax call, and then to return the generated JSON. Any help would be much appreciated.

Here's a generic version of what I have so far:


Ext.ns( 'Company.util.MyProxy' );

Company.util.MyProxy = Ext.extend(Ext.data.DataProxy, {

initComponent: function( config ) {
Ext.apply( this, config );
Company.util.MyProxy.superclass.initComponent.call(this);
},

doRequest : function(action, rs, params, reader, cb, scope, arg) {

// I want to call a javascript function that returns JSON, and return
// that JSON back to the store that uses this proxy.

var jsonResult = this.myFunction(params);

// ??? what goes here to avoid an Ajax call and simply return the json to the reader/store?

},

myFunction: function( params ) {

// ... this function calls a javascript API and returns a JSON string

Company.util.some_API_call({
limit: params.limit,
start: params.start,
success: function onSuccess(json) {
return json;
},
failure: function onFailure(error,status) {
//alert(" error message text ");
return [];
}

});
}

});

Ext.reg('MyProxy', Company.util.MyProxy);

darthwes
5 Nov 2010, 2:44 PM
You could extend DirectProxy, HttpProxy, MemoryProxy, or ScriptTagProxy. Alternatively you could write your own proxy, but you would have to use the same kind of funky Ext.extend with the mystery third parameter. Not like that's hard, just copy the HttpProxy code from the source and tailor fit?

plalx
5 Nov 2010, 10:54 PM
Hi, not sure exactly what you are trying to do, but I created an example that might help...

You pass a function to the FunctionProxy constructor. The function will get called with the arguments provided to the store.load function. The provided function must return a valid JSON object for the reader.



FunctionProxy = Ext.extend(Ext.data.DataProxy, {
constructor: function(fn) {
var api = {};
api[Ext.data.Api.actions.read] = true;
FunctionProxy.superclass.constructor.call(this, {
api: api
});

this.fn = fn;
},
doRequest : function(action, rs, params, reader, callback, scope, arg) {

params = params || {};
var result;
try {
result = reader.readRecords(this.fn(params));
} catch(e) {
// @deprecated loadexception
this.fireEvent("loadexception", this, null, arg, e);
this.fireEvent('exception', this, 'response', action, arg, null, e);
callback.call(scope, null, arg, false);
return;
}
callback.call(scope, result, arg, true);
}

});

var store = new Ext.data.JsonStore({
root: 'data',
idProperty: 'id',
totalProperty: 'count',
fields: ['id', 'text'],
proxy: new FunctionProxy(function() {
return {
data: [
{ id: 1, text: 'Test' },
{ id: 2, text: 'Test 2' }
],
count: 2,
success: true,
message: ''

};
}),
listeners: {
'load': function() {
console.log(this.getCount());
}
}
});

store.load();

Condor
5 Nov 2010, 11:39 PM
Are you trying to write PagingMemoryProxy (ext/examples/ux/PagingMemoryProxy.js) yourself?

ps. If you are, I would recommend using the PagingStore user extension instead.

joeloftus
9 Nov 2010, 12:46 PM
Thanks for the suggestions. PagingStore was very close to what I needed. MemoryProxy was essentially the solution. With this and some help from a coworker I found a solution. my 'doRequest()' now looks like this:


doRequest : function(action, rs, params, reader, cb, scope, arg) {

myNameSpace.myFunction({

start: params.start,
limit: params.limit,

success: function onSuccess( json ) {

params = params || {};
var result;
try {
result = reader.readRecords( json );
} catch(e) {
this.fireEvent("loadexception", this, null, arg, e);
callback.call(scope, null, arg, false);
return;
}
callback.call(scope, result, arg, true);

},

failure: function onFailure(error) {
alert("Got an error: " + error);
}

});

}


This loads the reader/store with JSON coming from the call to "myNameSpace.myFunction". PagingToolbar plays nicely with this without modification. Now I'm working on inverting the structure so that I have just one generic proxy component that will work for multiple different functions that return JSON.

plalx
9 Nov 2010, 1:09 PM
Just use the code I posted above... it does that already... no?

joeloftus
9 Nov 2010, 1:50 PM
Yes your code does that. The difference is that I had to wrap the pre-existing doRequest proxy logic inside of my function instead of the other way around due to timing issues with the callback from my function.

We considered two refactor possibilities: 1) passing in the function as your code does, or 2) breaking up the proxy and specific json-producing functions using Observable objects and event handling. I'm going to do it both ways so I can weigh the pros and cons. Thanks again!