ExtJS: Reload datastore without redrawing grid
(E开发者_如何转开发xtJS 3.3.1)
How can I save the scroll position of a grid after I call grid.store.reload()?
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.
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 setTimeout
s and defer
s in Firefox. Try saving the scroll state using var state = view.getScrollState()
, then restore it with view.restoreScroll.defer(1, state)
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.
listeners: {
beforerefresh: function(v) {
v.hide();
},
refresh: function(v) {
v.show();
}
}
worked for me (add in view config)
This post recently helped me find that the view maintains the control over the scrollState. I was able to view.saveScrollState() then defer view.restoreScrollState() with a timeOut. The longer the timeout the more jarring the return is, so be aware that you want the minimum amount of timeOut for the view to refresh / render. What was missing from earlier posts was that the view has a "saveScrollState" where it stores scroll position internally.
view.saveScrollState();
//do some things here
setTimeout(function(){
view.restoreScrollState();
},1);
精彩评论