Saturday, May 31, 2008

Ext.apply and Ext.applyIf

In case you missed it, last weekend Jay Garcia released his third screencast in which he explains Ext.apply.

Here is the video, a short 7 and something minutes long, which is a fresh alternative of reading plain blog posts. :-)





Jay actually mentions a firebug bug which I wasn't aware of but which I encountered just this week after learning about it in his screencast. The bug is that the properties of an object you are inspecting (after clicking on the your object which is printed to your console via console.log(object) or console.info(object)) might not be the actual current ones. The work-around is to print directly the property you want to inspect via console.log(object.property).

If you're a little confused about the defaults (third) parameter of Ext.apply, then just think of it as you would write the the following

Ext.apply(receiver, defaults);
Ext.apply(receiver, source);

// is the same as
Ext.apply(receiver, source, defaults);


Also note that there is an Ext.applyIf method (without a third parameter) which only assigns properties/attributes to the receiver object if they aren't existing in the receiver object yet.

And as a small extra here's a real-world example of using Ext.apply which I implemented this week:

onBeforeLoad: function(store, options) {
options.params = options.params || {};
this.cleanParams(options.params);
var params = this.buildQuery(this.getFilterData());
if (store.lastOptions && store.lastOptions.params) {
options.params = Ext.apply(store.lastOptions.params, options.params);
}
Ext.apply(options.params, params);
}

I'm overwriting here the onBeforeLoad method from the excellent Ext.ux.GridFilter extension which is executed every time before the store is loading.
So if you load the store the first time via store.load({params: {start: 0, limit: 50}}), it will resend these parameters when the store is reloaded after you changed your filter values or after you manually executed store.load() after you saved changes to your EditorGridPanel for example. Moreover, the lastOptions params will be overwritten when you switch to the next page via your PagingToolbar, which calls something like store.load({params: {start: 50, limit: 50}}).

3 comments:

mjlecomte said...

RE: the firebug bug. Instead of using log use console.dir. I mostly notice that 'bug' with trying to do console.log(this). Console.dir(this) or any other object appears to give accurate account.

Eduard Bondarenko said...

How do you solve problem that ExtJS sends POST requests when see parameters?

pagination to :index method of resource became POST and invalid.

Thanks in advance.

Steffen Hiller said...

Hey Eduard,

you can pass the method option to the load method, i.e.:
grid.store.load({ url: ..., method: 'GET'})

I overrode the load method of the HttpProxy class to always use the GET method.

Here is my code. It's only been tested with Ext JS 2.1. (sorry the code formatting, I can't format it here in the comments right)

Ext.override(Ext.data.HttpProxy, {

load : function(params, reader, callback, scope, arg){
if(this.fireEvent("beforeload", this, params) !== false){
var o = {
params : params || {},
request: {
callback : callback,
scope : scope,
arg : arg
},
reader: reader,
callback : this.loadResponse,
scope: this,
method: 'GET'
};
if(this.useAjax){
Ext.applyIf(o, this.conn);
if(this.activeRequest){
Ext.Ajax.abort(this.activeRequest);
}
this.activeRequest = Ext.Ajax.request(o);
}else{
this.conn.request(o);
}
}else{
callback.call(scope||this, null, arg, false);
}
}

});

I basically only added the method: 'GET' line after the scope: this line. If you have a new Ext version, copy the load method from the HttpProxy class from the ext-all-debug.js file or src folder and put it in the override method. Don't forget the comma at the end of the scope: this line.

Hope that helps,
Steffen