具有远程过滤器和排序功能的ExtJS无限滚动网格 [英] ExtJS Infinite Scroll Grid with remote Filters and Sort
问题描述
在ExtJS 4.1 beta 2中,我设法通过远程存储实现了无限滚动网格。我基本上采用了一个现有的(完全可操作的)分页网格(带有远程存储,过滤和排序功能),然后放入适当的配置以进行无限滚动:
In ExtJS 4.1 beta 2 I managed to implement an infinite scroll grid with a remote store. I basically took an existing (fully operational) paging grid (with remote store, filtering and sorting) and then put in the appropriate configs for infinite scrolling:
// Use a PagingGridScroller (this is interchangeable with a PagingToolbar)
verticalScrollerType: 'paginggridscroller',
// do not reset the scrollbar when the view refreshs
invalidateScrollerOnRefresh: false,
// infinite scrolling does not support selection
disableSelection: true,
在文档(请参阅无限滚动部分),但是您需要将商店设置为具有 buffered:true
配置。而且您无法使用 store.load()
进行加载,需要这样做:
It doesn't say this anywhere in the docs(see Infinite Scrolling section), but you need to set your store to have buffered: true
config. And you can't load with store.load()
it needs to be done like this:
store.prefetch({
start: 0,
limit: 200,
callback: function() {
store.guaranteeRange(0, 99);
}
});
所有这些,如果我缓慢滚动从而允许数据预取,一切都会很好用,不要
With all that, everything works great if I scroll slowly and thus allow the data to prefetch, don't use any filters and don't use any sorting.
但是,如果我快速滚动或尝试在激活过滤器时或在对其进行排序时尝试使无限滚动网格重新加载,请不要使用任何过滤器一切都破裂了。错误是选项未定义
。
However, if I scroll fast or try to make the infinite scroll grid reload with a filter active or while sorting it all breaks apart. Error is options is undefined
.
我花了几个小时在代码中进行了一些跟踪和谷歌搜索除了得出结论,没有人使用远程过滤器和远程滚动实现无限滚动网格外,我发现以下内容:
I've spent a couple of hours doing some tracing in the code and googling and aside from concluding that no one has implemented an infinite scroll grid with remote filters and remote scrolling, I have found the following:
由于这种方法,过滤器崩溃了在 Ext.data.Store
中,当无限滚动条需要从服务器获取更多数据时,它将被调用:
The filtering is breaking down because of this method in Ext.data.Store
which is called by the infinite scroller when it needs more data from the server:
mask: function() {
this.masked = true;
this.fireEvent('beforeload');
},
由于某种原因,此方法会触发 beforeload
事件没有 Ext.data.Operation
参数,该参数应该是指定的一部分此处。
For some reason, this method fires the beforeload
event without the Ext.data.Operation
parameter which is supposed to be part of it as specified here.
结果,在 Ext.ux.grid.FiltersFeature
onbeforeload 处理程序中发生错误>因为选项当然是未定义的:
As a result, an error occurs in the onbeforeload
handler in Ext.ux.grid.FiltersFeature
because of course "options" is undefined:
/**
* @private
* Handler for store's beforeload event when configured for remote filtering
* @param {Object} store
* @param {Object} options
*/
onBeforeLoad : function (store, options) {
options.params = options.params || {};
this.cleanParams(options.params);
var params = this.buildQuery(this.getFilterData());
Ext.apply(options.params, params);
},
我可以切断对此<$ c的呼叫PagingScroller代码中的$ c> mask 方法,然后滚动功能很棒。我可以根据需要快速滚动,并且可以正确加载数据。 但是然后过滤器和排序不会应用于ajax请求。
I can cut out the call to this mask
method from the PagingScroller code and then the scroll functionality is great. I can scroll as fast as I like and it loads the data properly. But then filters and sort does not get applied to the ajax requests.
我在排序方面的投入还不多,但我认为与此 mask
方法类似,因为sort只是操作
对象包含的另一个元素,它会导致没有操作对象传递给ajax请求。
I haven't dived as much into the sorting aspect but I think it something similar with this mask
method because sort is simply another element contained by the operation
object and it causes no operation object to be passed to the ajax request.
我在想,如果我能弄清楚如何强制 mask
方法使用 operation
参数触发 beforeload
(就像文档说的那样)应该)一切都会好的。问题是,我还无法弄清楚该怎么做。有什么建议吗?
I'm thinking that if I could just figure out how to force the mask
method to fire beforeload
with the operation
parameter (like the docs say it is supposed to) everything will be fine. Problem is, I haven't been able to figure out how to do that. Any suggestions?
如果有人只是告诉我我错了,而实际上人们已经做了这项工作,那我会很受启发,但是您使用的任何替代代码段处理这个问题或链接将不胜感激。
If someone would just tell me that I am wrong and people have in fact made this work, I would be inspired, but a snippet of any overrides you used to handle this problem or a link would be much appreciated.
我还尝试将其降级到4.0.7和4.0.2a,并且得到相同的结果,所以它不仅仅是测试版问题。
I've also tried downgrading to 4.0.7 and 4.0.2a and I get the same results, so it isn't just a beta problem.
更新-2012年2月7日:
这似乎实际上是一个 Ext.ux.grid.FilterFeature
问题,而不是无限滚动的问题。如果我删除FilterFeature配置,则无限滚动效果很好,并且在按列排序时确实会将排序参数传递给我的后端。我将开始研究FilterFeature的结尾。
This seems like it may actually be a Ext.ux.grid.FilterFeature
problem not an infinite scrolling problem. If I remove the FilterFeature config entirely infinite scrolling works great and does pass the sorting params to my backend when I sort by a column. I will start looking into the FilterFeature end of things.
推荐答案
成功!我可以无限滚动工作使用远程过滤器和远程排序(这是4.1 beta 2中的版本,但是因为我在4.02a和4.0.7中遇到了相同的错误,所以我想它也可以解决这些错误)。基本上,我只需要在代码中添加一些替代。
SUCCESS! I have infinite scrolling working with a remote filter and remote sort (this is in 4.1 beta 2, but because I was getting the same errors in 4.02a and 4.0.7 I imagine that it would resolve those too). Basically, I just had to add a few overrides in my code.
我还没有在其他浏览器中进行过测试,但是我已经在FF中进行了测试。这是我使用的替代项:
I haven't done testing in other browsers but I have it going in FF. Here are the overrides that I am using:
Ext.override(Ext.data.Store, {
// Handle prefetch when all the data is there and add purging
prefetchPage: function(page, options, forceLoad) {
var me = this,
pageSize = me.pageSize || 25,
start = (page - 1) * me.pageSize,
end = start + pageSize;
// A good time to remove records greater than cache
me.purgeRecords();
// No more data to prefetch
if (me.getCount() === me.getTotalCount() && !forceLoad) {
return;
}
// Currently not requesting this page and range isn't already satisified
if (Ext.Array.indexOf(me.pagesRequested, page) === -1 && !me.rangeSatisfied(start, end)) {
me.pagesRequested.push(page);
// Copy options into a new object so as not to mutate passed in objects
options = Ext.apply({
page : page,
start : start,
limit : pageSize,
callback : me.onWaitForGuarantee,
scope : me
}, options);
me.prefetch(options);
}
},
// Fixes too big guaranteedEnd and forces load even if all data is there
doSort: function() {
var me = this;
if (me.buffered) {
me.prefetchData.clear();
me.prefetchPage(1, {
callback: function(records, operation, success) {
if (success) {
guaranteeRange = records.length < 100 ? records.length : 100
me.guaranteedStart = 0;
me.guaranteedEnd = 99; // should be more dynamic
me.loadRecords(Ext.Array.slice(records, 0, guaranteeRange));
me.unmask();
}
}
}, true);
me.mask();
}
}
});
Ext.override(Ext.ux.grid.FiltersFeature, {
onBeforeLoad: Ext.emptyFn,
// Appends the filter params, fixes too big guaranteedEnd and forces load even if all data is there
reload: function() {
var me = this,
grid = me.getGridPanel(),
filters = grid.filters.getFilterData(),
store = me.view.getStore(),
proxy = store.getProxy();
store.prefetchData.clear();
proxy.extraParams = this.buildQuery(filters);
store.prefetchPage(1, {
callback: function(records, operation, success) {
if (success) {
guaranteeRange = records.length < 100 ? records.length : 100;
store.guaranteedStart = 0;
store.guaranteedEnd = 99; // should be more dynamic
store.loadRecords(Ext.Array.slice(records, 0, guaranteeRange));
store.unmask();
}
}
}, true);
store.mask();
}
});
我的商店配置如下:
// the paged store of account data
var store = Ext.create('Ext.data.Store', {
model: 'Account',
remoteSort: true,
buffered: true,
proxy: {
type: 'ajax',
url: '../list?name=accounts', //<-- supports remote filter and remote sort
simpleSortMode: true,
reader: {
type: 'json',
root: 'rows',
totalProperty: 'total'
}
},
pageSize: 200
});
网格为:
// the infinite scroll grid with filters
var grid = Ext.create('Ext.grid.Panel', {
store: store,
viewConfig: {
trackOver: false,
singleSelect: true,
},
features: [{
ftype: 'filters',
updateBuffer: 1000 // trigger load after a 1 second timer
}],
verticalScrollerType: 'paginggridscroller',
invalidateScrollerOnRefresh: false,
// grid columns
columns: [columns...],
});
此外,初始加载必须像这样完成(不仅仅是store.load()):
Also the initial load must be done like this (not just store.load()):
store.prefetch({
start: 0,
limit: 200,
callback: function() {
store.guaranteeRange(0, 99);
}
});
这篇关于具有远程过滤器和排序功能的ExtJS无限滚动网格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!