Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ExtJS: Reload datastore without redrawing grid

(ExtJS 3.3.1)

How can I save the scroll position of a grid after I call grid.store.reload()?

like image 436
Ron Avatar asked Feb 22 '11 16:02

Ron


3 Answers

I managed to fix it like this:

this.store = new Ext.data.Store({
    listeners:{
        'load':function (store, records, options) {
            var restoreScroll = function(scrollState){
                grid.getView().restoreScroll(scrollState);
            };
            if (grid.view && grid.view.scroller){
                _.delay(restoreScroll, 10,grid.getView().getScrollState());
            }
        }
    }, ...
}

As you can see, I use _.delay (of the underscore.js framework). It's just like a setTimeout.

A more optimized version, not using the the function 'restoreScroll' didn't work out. I think that the view is changed when restoreScroll is called. I had to take 10 miliseconds. 1 was not enough. As stated by others, ext.js uses a lot of defer-calls.

like image 99
Paul Mestrum Avatar answered Oct 05 '22 20:10

Paul Mestrum


That's two different questions.

First, to reload a store without redrawing the grid, use store.suspendEvents(), then call store.resumeEvents() in the load callback.

Restoring scroll position after refresh is a bit more tricky, particularly since ExtJS makes excessive use of setTimeouts and defers in Firefox. Try saving the scroll state using var state = view.getScrollState(), then restore it with view.restoreScroll.defer(1, state)

like image 40
user123444555621 Avatar answered Oct 05 '22 20:10

user123444555621


Finally I found this section in the extjs grid faq. This snipped does not directly run in webkit-browsers. You have to add a timeout and call the restore part a little moment later. 100ms helped me out here. This is what I have now:

grid.getView().on('beforerefresh', function(view) {
  view.scrollTop = view.scroller.dom.scrollTop;
  view.scrollHeight = view.scroller.dom.scrollHeight;
});

grid.getView().on('refresh', function(view) {
    setTimeout(function () {
        view.scroller.dom.scrollTop = view.scrollTop + (view.scrollTop == 0 ? 0 : view.scroller.dom.scrollHeight - view.scrollHeight);
    }, 100);
});

Runs in IE8, Chrome9, Firefox3.6

Does not in Opera 11

This solution has one drawback: Without activly telling the view not to restore the scroll position it is also restored if you goto next page by the paginator.

I think sencha should integrate this feature as a option, because it is a deep integration to tell the view of a grid to restore the position if a store reloads the same position of a datasource and not to do so if changes to the baseparams are made... or so.

like image 23
Ron Avatar answered Oct 05 '22 18:10

Ron