extjs版本2.1
用extjs的分组store加载数据遇到一个问题,首先store定义如下:
var store = new Ext.data.GroupingStore({
reader: new BidResultItemXmlReader(),
url: Ipms.StateAssetOfficeService + '/QueryBidResultItem',
sortInfo: { field: 'id', direction: "DESC" },
groupField: 'groupField'
});
单从字面分析这段代码:从url加载数据,并且按id进行降序排序,然后按groupField字段分组。
但是最终页面展现的数据,却不是这样的,如下图:
而后台发送的数据的确是按id降序排列的。
原因就是对Ext排序、分组不够了解,仅仅从字面上进行臆断。
1.Store.js中加载数据的方法loadRecords()源码如下:
loadRecords : function(o, options, success){
// ...
this.applySort(); // 会调用GroupingStore的方法
// ..
}
2.GroupingStore.js中applySort()源码:
applySort : function(){
Ext.data.GroupingStore.superclass.applySort.call(this);
if(!this.groupOnSort && !this.remoteGroup){
var gs = this.getGroupState();
if(gs && gs != this.sortInfo.field){ // 凶手
this.sortData(this.groupField); // 调用Store的方法
}
}
},
从源码可知,只要我们的排序字段跟分组字段不是相同列的话,他都会再次按分组字段排序。
3.Store.js中sortData()源码:
// private
sortData : function(f, direction){
direction = direction || 'ASC';
var st = this.fields.get(f).sortType;
var fn = function(r1, r2){
var v1 = st(r1.data[f]), v2 = st(r2.data[f]);
return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
};
this.data.sort(direction, fn);
if(this.snapshot && this.snapshot != this.data){
this.snapshot.sort(direction, fn);
}
},
4. 之所以进行分组之前首先按分组字段进行排序,个人臆断原因有二。
A. 排序字段跟分组字段不同,即使排好序后,分组还是有可能打破排序的顺序的。
B. 跟GroupingView的写法有关系,见下文。
5.GroupingView.js的doRender()源码(有删减):
doRender : function(cs, rs, ds, startRow, colCount, stripe){
var groups = [], curGroup, i, len, gid;
for(i = 0, len = rs.length; i < len; i++){
var rowIndex = startRow + i;
var r = rs[i],
gvalue = r.data[groupField],
g = this.getGroup(gvalue, r, rowIndex, colIndex, ds);
if(!curGroup || curGroup.group != g){ // 关键
curGroup = {
group: g,
gvalue: gvalue,
groupId: gid,
startRow: rowIndex,
rs: [r]
};
groups.push(curGroup);
}else{
curGroup.rs.push(r);
}
r._groupId = gid;
}
}
此方法就是构造分组列表,简单的说,他会循环GroupStore中的每个条目,判断如果groupField的值跟当前组的值相同,则把此条目放入当前分组;否则的话,新建一个分组。
他这么做,就是假设store是按照groupField进行了排序。从applySort()方法中,我们发现他会强制按groupField进行升序排序。这也正是导致最终视图的原因。
6.说些风凉话。在服务端排序在客户端分组,事件很不靠谱的事儿。Ext的处理方式就更不靠谱了(简单看了一下3.2中的处理就优雅多了)。
7. 折中的办法:按照某个字段分组,然后组内的条目按照某某字段分组。所以,干脆把排序和分组要么都放在服务器端,客户端不处理;要么都放在客户端,服务器端不干预。
8.我们采用排序和分组都在服务器端完成,有一定的局限性
var store = new Ext.data.GroupingStore({
reader: new BidResultItemXmlReader(),
url: Ipms.StateAssetOfficeService + '/QueryBidResultItem',
sortInfo: { field: 'id', direction: "DESC" },
remoteSort: true, // 配置1
remoteGroup: true,// 配置2
groupField: 'groupField'
});
转载于:https://blog.51cto.com/wangyuelucky/1341614
本文深入解析了使用Ext JS的分组Store加载数据时,排序与分组之间的交互作用,解释了为何在客户端进行分组前会先按分组字段进行排序,以及这种处理方式可能导致的数据展示顺序与预期不符的情况。提出了折中解决方案,建议根据实际情况选择排序和分组操作的位置,以避免不必要的误解和调整。

3732

被折叠的 条评论
为什么被折叠?



