PDA

View Full Version : ScriptTagProxy and building dynamic URLs



jdice19
15 Nov 2013, 7:39 AM
I currently have a ScriptTagProxy setup with the host portion of the URL that remains the same. I would like to append onto that different locations based on the user. For example

The proxy has as its url host.com. If the user logins as jsmith, I want to append jsmith onto the Url at runtime so it becomes host.com/jsmith. I see in the docs that there is a buildURL function that is only avaliable to the DataProxy class (and only when I search in the top bar, it doesn't show up on that page otherwise).

My questions then. In the buildUrl function in the proxy I can specifiy the data. However I have trouble passing in the values to put into the Url.

Relevant Code

proxy: new Ext.data.ScriptTagProxy{
url: 'http://host.com',
buildUrl: function (request) {
return this.url + '/placefolder/'+request.params['userName']
}
}
...
grid.store.load({
params: {

userName: 'jsmith'

}
})


I always get back that request.params is null. Any suggstions?

slemmon
19 Nov 2013, 3:57 PM
The buildUrl method signature doesn't pass the request object as the first param in Ext 3 and it looks like the trans property with the passed load params isn't bound to the proxy instance when buildUrl is called. You might need to listen to the beforeLoad event and modify the URL there instead.

http://docs.sencha.com/extjs/3.4.0/#!/api/Ext.data.ScriptTagProxy-event-beforeload

jdice19
20 Nov 2013, 7:01 AM
Trying to modify the URL in the beforeLoad with

store.proxy.url = '/'+params.userLoginName;
results in that segment being ignored and the proxy only using the url specified in the setup. It doesn't appear there is a setURL function that allows me to just modify the url in the ScriptTagProxy.

If I try to change the api using the setApi function, it appends localhost in front of the url rather than just the url domain I specified in the original proxy setup.

Any suggestions?

slemmon
20 Nov 2013, 9:25 AM
See if this example works for you:

1mb

jdice19
20 Nov 2013, 10:29 AM
That worked great slemmon. Interesting that where I redefine the proxy API determines if localhost is inserted before the URL.

I have a followup question then. It appears that I am getting the callbackParam appended on at the end of the URL. I can specifiy the name of the callbackParam, ie if I set callbackParam to fncCallback I get appended to my URL fncCallback=stcCallback1001. After looking through the docs I don't see that there is a way to define the actual parameter of the function that I want to use. Do you have any pointers in that direction?

slemmon
20 Nov 2013, 10:52 AM
In Ext3.x the callback function name is not configurable. You'd need to extend Ext.data.ScriptTagProxy and override the doRequest method looks like.

jdice19
20 Nov 2013, 11:48 AM
Ext.override(Ext.data.ScriptTagProxy, {
doRequest : function(action, rs, params, reader, callback, scope, arg) {

var p = Ext.urlEncode(Ext.apply(params, this.extraParams));
var url = this.buildUrl(action, rs)
;//Remove callback from URL here

slemmon are you talking about something like this? If so, I have some more beginner questions then.
Does this override need to exist in the same file where I'm creating the store/proxy?
Will this cause problems if I specify no callback function value at all? Or will specifying the same callback function cause problems if there is no increment?
Thanks

slemmon
20 Nov 2013, 12:45 PM
You'll extend the ScriptTagProxy class to make your own using the extend method:
http://docs.sencha.com/extjs/3.4.0/#!/api/Ext-method-extend

Something like:


MyApp.data.ScriptTagProxy = Ext.extend(Ext.data.ScriptTagProxy, {
callbackName: 'stcCallback',
doRequest: function (action, rs, params, reader, callback, scope, arg) {
var p = Ext.urlEncode(Ext.apply(params, this.extraParams));


var url = this.buildUrl(action, rs);
if (!url) {
throw new Ext.data.Api.Error('invalid-url', url);
}
url = Ext.urlAppend(url, p);


if (this.nocache) {
url = Ext.urlAppend(url, '_dc=' + (new Date().getTime()));
}
var transId = ++Ext.data.ScriptTagProxy.TRANS_ID;
var trans = {
id: transId,
action: action,
cb: this.callbackName + transId,
scriptId: this.callbackName + transId,
params: params,
arg: arg,
url: url,
callback: callback,
scope: scope,
reader: reader
};
window[trans.cb] = this.createCallback(action, rs, trans);
url += String.format("&{0}={1}", this.callbackParam, trans.cb);
if (this.autoAbort !== false) {
this.abort();
}


trans.timeoutId = this.handleFailure.defer(this.timeout, this, [trans]);


var script = document.createElement("script");
script.setAttribute("src", url);
script.setAttribute("type", "text/javascript");
script.setAttribute("id", trans.scriptId);
this.head.appendChild(script);


this.trans = trans;
}


});


And then you can use new MyApp.data.ScriptTagProxy() as a proxy (you may need to set a namespace (http://docs.sencha.com/extjs/3.4.0/#!/api/Ext-method-ns) first).

And you could remove the increment on the callback name, but you'd risk collisions if more than one proxy call happened at a time.

jdice19
20 Nov 2013, 1:08 PM
Thanks, I saw an example like that when I was googling but I wasn't sure if I could apply it to my case as well. If I'm expecting that the user will never make calls asynchronous-ly then I think the collision problem can be avoided.

Another thing I was wondering then is if it would make sense to transform my beforeLoad function and put the logic of dictating which URL I'm building into the doRequest function since all the params I would need are there. Is there a reason why that would be a bad idea?

slemmon
22 Nov 2013, 10:33 PM
That seems ok to me.