PDA

View Full Version : Suggestion for Store: Easy reload



Belgabor
27 Feb 2007, 9:32 PM
Hi,

during my last cruise through the source I noticed that there is no simple way to reload the current grid page. All I could spot would require access to private variables of Store or PagingToolBar. Maybe it would be possible, but probably really cumbersome. I'd suggest either adding a reload method to Store or changing the behaviour of load so it reloads the current state if no parameters are passed:

Ext.extend(Ext.data.Store, Ext.util.Observable, {
remoteSort : false,
lastOptions : {},

<...>

load : function(options){
options = options || lastOptions;
if(this.fireEvent("beforeload", this, options) !== false){

JeffHowden
27 Feb 2007, 10:05 PM
I think it'd be as simple as the following bit added to Store.js

reload : function(){
this.load(this.lastOptions);
},

Jack?

jack.slocum
28 Feb 2007, 9:29 AM
This is what I put in:


reload : function(options){
this.load(Ext.applyIf(options||{}, this.lastOptions));
},

This way you can also override things or provide a callback/scope if you want.

Belgabor
28 Feb 2007, 10:30 AM
Fantastic, thanks.

corinth
19 Mar 2007, 9:29 PM
Jack,

This is a good enhancement, but I wonder if it shouldn't be taken further. Here's the design pattern I'm thinking of and have implemented in our own app.

- We have a Grid that displays unfiltered data by default
- Users can filter the data by entering values in a Form.
- A Search button is bound to a JS handler that processes the user input.
- The handler for the button click basically does the following:
---- Creates an object based on the Form input (e.g. {field1=blah, field2=xyz, etc...}
---- Calls ds.load passing a params object that includes the form data, start, and limit: (e.g. params looks like: {field1=blah, field2=xyz, start=0, limit=25}
---- ds.load calls storeOptions and saves all the parameters
---- [Optionally updates the proxy on the Store for the Grid. Interestingly, we tried this first by default, but the "params" of the Proxy are useless for each subsequent invocation of request on the Connection object]

This approach works fine for the first page of data, but when you click next using a PagingToolbar, ds.load is invoked and the options previously stored are overwritten with the updated params from the Toolbar's call.

That seems counter-intuitive to me: wouldn't we want the PagingToolbar's next/prev/etc. to simply operate on the Store exactly as it was on the first page of data?

A couple workarounds come to mind right away:

- Change the Store's Proxy URL to be the URL + the form data as a query string.
(This works, but forces you into using GET and is hackish)

- PagingToolbar should call ds.reload for each onClick event.
(This does NOT work by default, because reload uses Ext.applyIf on the options object, but any parameters to the intial request are an object that is a property of options and lastOptions. applyIf only copies properties that don't exist, but it doesn't take care of copying properties of "nested" objects).

Here are the changes I made to make the latter approach work the way I thought it ought to:

PagingToolbar


onClick : function(which){
var ds = this.ds;
switch(which){
case "first":
ds.reload({params:{start: 0, limit: this.pageSize}});
break;
case "prev":
ds.reload({params:{start: Math.max(0, this.cursor-this.pageSize), limit: this.pageSize}});
break;
case "next":
ds.reload({params:{start: this.cursor+this.pageSize, limit: this.pageSize}});
break;
case "last":
var total = ds.getTotalCount();
var extra = total % this.pageSize;
var lastStart = extra ? (total - extra) : total-this.pageSize;
ds.reload({params:{start: lastStart, limit: this.pageSize}});
break;
case "refresh":
ds.reload({params:{start: this.cursor, limit: this.pageSize}});
break;
}
},


And in Store


reload : function(options) {
// temporary changes
Ext.applyIf(options||{}, this.lastOptions);
Ext.applyIf(options.params||{}, this.lastOptions.params);

this.load(options);
},


Thoughts? Am I, perhaps, way off and missing a better approach?

Thanks,

Chris

JeffHowden
19 Mar 2007, 9:49 PM
The answer is to attach a listener to the beforeload event. In fact, doing so makes passing the extra baseParams to your backend dynamically a surprisingly simple task. More here:

http://yui-ext.com/forum/viewtopic.php?t=3261

The important bit is the block of code at the bottom.

jack.slocum
20 Mar 2007, 5:40 AM
Also, when doing server side filtering and you want the store to maintain the params until explicitly cleared, use the baseParams object.

store.baseParams = {
// your filtering criteria
};

store.load(...);

The all subsequent loads by the paging toolbar (or other loads) will contain the filtering params. That's how I do it in the Ext bug tracker as well.

corinth
20 Mar 2007, 6:55 AM
*smacks forehead*

I was staring at that code so much I got tunnel vision and missed the baseParams sitting right in front of me. Thanks for the answer folks.

Chris