本人在工作中发现Ext.grid.PivotAxis的一个Bug。虽然说这玩意儿是一个半成品,新版本的EXTJS中已经找不到踪影,但是还是发表一下,以备用到过这玩意儿的程序员借鉴。已经在EXTJS的论坛报BUG :[url]http://www.sencha.com/forum/showthread.php?262138-A-bug-in-Ext.grid.PivotAxis [/url] 懒得看英文的话,在下在这里再解释一下。
该类的buildHeaders方法有如下代码片段
buildHeaders: function() {
var tuples = this.getTuples(),
rowCount = tuples.length,
dimensions = this.dimensions,
dimension,
colCount = dimensions.length,
headers = [],
tuple, rows, currentHeader, previousHeader, span, start, isLast, changed, i, j;
for (i = 0; i < colCount; i++) {
dimension = dimensions[i];
rows = [];
span = 0;
start = 0;
for (j = 0; j < rowCount; j++) {
tuple = tuples[j];
isLast = j == (rowCount - 1);
currentHeader = tuple.data[dimension.dataIndex];
/*
* 'changed' indicates that we need to create a new cell. This should be true whenever the cell
* above (previousHeader) is different from this cell, or when the cell on the previous dimension
* changed (e.g. if the current dimension is Product and the previous was Person, we need to start
* a new cell if Product is the same but Person changed, so we check the previous dimension and tuple)
*/
changed = previousHeader != undefined && previousHeader != currentHeader;
if (i > 0 && j > 0) {
changed = changed || tuple.data[dimensions[i-1].dataIndex] != tuples[j-1].data[dimensions[i-1].dataIndex];
}
if (changed) {
rows.push({
header: previousHeader,
span : span,
start : start
});
start += span;
span = 0;
}
......
该方法先循环列,再循环行,扫描计算是不是要画新的cell,计算之前的dimension的span。其中有一个逻辑不对,它只检查和上面一行的cell,或者之前一列上下行是否一样。而我认为需要检查当前cell之前的所有列的上下行是否一致。否则画出来的表格会比右边的数据行数少。把下面的文件放在examples\grid下去测一下就会发现:
<!DOCTYPE HTML>
<html>
<head>
<title>Test Page</title>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<meta http-equiv="X-UA-Compatible" content="IE=8">
<!-- EID Theme CSS -->
<!-- ** CSS ** -->
<!-- base library -->
<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
<!-- overrides to base library -->
<!-- page specific -->
<link rel="stylesheet" type="text/css" href="../shared/examples.css" />
<link rel="stylesheet" type="text/css" href="grid-examples.css" />
<!-- ** Javascript ** -->
<!-- ExtJS library: base/adapter -->
<script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
<!-- ExtJS library: all widgets -->
<script type="text/javascript" src="../../ext-all-debug.js"></script>
<script type="text/javascript">
Ext.onReady(function() {
var SaleRecord = Ext.data.Record.create([
{name: 'D1', type: 'string'},
{name: 'D2', type: 'string'},
{name: 'D3', type: 'string'},
{name: 'D4', type: 'string'},
{name: 'D5', type: 'string'},
{name: 'D6', type: 'string'},
{name: 'D7', type: 'string'},
{name: 'D8', type: 'string'},
{name: 'M1', type: 'int'}
]);
var myData = [
{"id":"1","D1":"V1","D2":"Shanghai","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Hank","D7":"aa","D8":"d81","M1":"8888"},
{"id":"2","D1":"V1","D2":"Shanghai","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Hank","D7":"aa","D8":"d80","M1":"8887"},
{"id":"3","D1":"V1","D2":"Shanghai","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Hank","D7":"aa","D8":"d87","M1":"8886"},
{"id":"4","D1":"V2","D2":"Beijing","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Adam","D7":"ab","D8":"d86","M1":"7878"},
{"id":"5","D1":"V2","D2":"Beijing","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Adam","D7":"ac","D8":"d85","M1":"7878"},
{"id":"6","D1":"V2","D2":"Beijing","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Adam","D7":"ab","D8":"d84","M1":"7878"},
{"id":"7","D1":"V2","D2":"Beijing","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Adam","D7":"ab","D8":"d82","M1":"7878"},
{"id":"8","D1":"V2","D2":"Boston","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Adam","D7":"ac","D8":"d81","M1":"3333"},
{"id":"9","D1":"V2","D2":"Boston","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Adam","D7":"er","D8":"d34","M1":"3333"},
{"id":"10","D1":"V2","D2":"Boston","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Apple","D7":"df","D8":"d80","M1":"7878"},
{"id":"11","D1":"V2","D2":"Boston","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Apple","D7":"df","D8":"d55","M1":"7878"}
];
// A simple store that loads SaleRecord data from a url
var myStore = new Ext.data.Store({
autoLoad: true,
proxy : new Ext.data.MemoryProxy(myData),
reader: new Ext.data.JsonReader({
}, SaleRecord),
});
// Create the PivotGrid itself, referencing the store
var pivot = new Ext.grid.PivotGrid({
title: 'PivotGrid example',
store : myStore,
aggregator: 'sum',
measure : 'M1',
renderTo : Ext.getBody(),
viewConfig: {
title: 'Sales Performance'
},
leftAxis: [
{
width: 60,
dataIndex: 'D1'
},
{
width: 150,
dataIndex: 'D2'
},
{
width: 60,
dataIndex: 'D3'
},
{
width: 60,
dataIndex: 'D4'
},
{
width: 60,
dataIndex: 'D5'
},
{
width: 60,
dataIndex: 'D6'
}
],
topAxis: [
{
dataIndex: 'D7'
},
{
dataIndex: 'D8'
}
]
});
});
</script>
</head>
<body>
</body>
</html>
所以我的fix如下:
isPrecedingChanged : function(tuples,dimensions,currentCol,currentRow){
var changed = false;
for(var col= currentCol; col>0; col--){
if(tuples[currentRow].data[dimensions[col-1].dataIndex] != tuples[currentRow-1].data[dimensions[col-1].dataIndex]){
changed = true;
break;
}
}
return changed;
},
buildHeaders: function() {
var me = this,
tuples = this.getTuples(),
rowCount = tuples.length,
dimensions = this.dimensions,
dimension,
colCount = dimensions.length,
headers = [],
tuple, rows, currentHeader, previousHeader, span, start, isLast, changed, i, j;
for (i = 0; i < colCount; i++) {
dimension = dimensions[i];
rows = [];
span = 0;
start = 0;
for (j = 0; j < rowCount; j++) {
tuple = tuples[j];
isLast = j == (rowCount - 1);
currentHeader = tuple.data[dimension.dataIndex];
/*
* 'changed' indicates that we need to create a new cell. This should be true whenever the cell
* above (previousHeader) is different from this cell, or when the cell on the previous dimension
* changed (e.g. if the current dimension is Product and the previous was Person, we need to start
* a new cell if Product is the same but Person changed, so we check the previous dimension and tuple)
*/
changed = previousHeader != undefined && previousHeader != currentHeader;
if (i > 0 && j > 0) {
changed = changed || me.isPrecedingChanged(tuples,dimensions,i,j);
}
if (changed) {
rows.push({
header: previousHeader,
span : span,
start : start
});
start += span;
span = 0;
}
.......
分享到:
相关推荐
每一项都是一个`Ext.grid.Column`实例。 - 示例:`columns: [{ header: '姓名', dataIndex: 'name' }, { header: '年龄', dataIndex: 'age' }]` 3. **autoExpandColumn** - 说明:此配置项指定了一个列ID,该列会...
这篇文章的标题指出这是一个关于“Ext.grid.plugin.RowEditing”的重构,版本为v1.4,发布日期为2011年9月11日。重构通常意味着代码的改进,可能涉及性能优化、错误修复或功能增强。在4.0版本中,RowEditing插件的...
Ext.grid.EditorGridPanel是Ext JS库中的一个组件,主要用于创建具有可编辑单元格的表格。这个组件在数据展示和编辑方面提供了丰富的功能,是构建数据密集型应用的理想选择。下面将详细阐述其特点、工作原理及如何...
Ext.override(Ext.grid.GridView, { scrollTop: function () { this.scroller.dom.scrollTop = 0; this.scroller.dom.scrollLeft = 0; }, scrollToTop: Ext.emptyFn }); ``` 这里的`scrollTop`方法将滚动条...
- **轻量级**:相比于`Ext.get`,`Ext.fly`更加轻量,因为每次调用都会创建一个新的`Ext.Element`实例,而不是缓存对象。 - **减少内存消耗**:对于只需要短暂操作的DOM元素而言,使用`Ext.fly`可以避免不必要的内存...
Ext.ux.touch.grid-master 是一个专门针对移动设备开发的JavaScript库,主要应用于开发触控友好的数据网格。这个压缩包包含的是EXTJS Touch框架的一个扩展组件,EXTJS Touch是Sencha公司开发的一个轻量级、高性能的...
Ext.grid.ColumnModel显示不正常
标题中的"extjs-Ext.ux.form.LovCombo下拉框"表明我们要讨论的是EXTJS中的一个特定组件,它是EXTJS的扩展插件,用于实现具有多选功能的下拉框。这个组件在处理火狐浏览器兼容性问题上做了优化,解决了在火狐浏览器下...
`Ext.grid.Grid`是Ext JS库中的一个组件,用于创建可交互的数据网格,而DWR(Direct Web Remoting)则是一种允许JavaScript和Java在浏览器端进行安全、高效通信的技术。本篇文章将深入探讨如何利用这两者结合,实现...
它接收一个DOM元素的ID或者一个DOM元素对象,返回一个`Ext.Element`对象。`Ext.Element`是对原生DOM元素的封装,提供了大量的实用方法,如样式设置、事件监听等。如果元素不存在,`Ext.get`会返回`null`。这是一个...
在Ext JS库中,`Ext.grid.plugin.RowExpander`是一个扩展插件,用于在网格行中添加可展开的详情区域。在Ext4.2版本中,用户可能遇到一个特定的问题,即`RowExpander`的`collapsebody`和`expandbody`事件无法正常触发...
在EXTJS库中,`Ext.Ajax.request`是用于发送Ajax请求的核心方法,它支持异步和同步操作。本文将详细解析如何利用`Ext.Ajax.request`实现同步请求,并探讨其背后的原理和注意事项。 首先,我们需要理解Ajax的本质,...
Ext.grid.GridPanel 删除线 放到example文件夹下运行
在使用`Ext.data.Store`之前,首先需要创建一个其实例。创建实例时需要指定其配置项,主要包括`proxy`和`reader`,这两个配置项分别用来定义数据来源以及如何解析这些数据。 ```javascript var data = [ ['boy', 0...
然而,获取`Ext.Store`的方式并不像获取其他Ext组件那样直接,因为Store并不是一个具有可视界面的组件,它是一个纯粹的数据容器。 在传统的创建`Ext.Store`的方法中,我们通常会这样定义一个Store: ```javascript...
标题"Ext.Ajax.request跨域"指出我们将探讨如何使用ExtJS库中的Ajax模块进行跨域请求。Ext.Ajax.request是ExtJS提供的一种发起Ajax请求的方式,它允许开发者向服务器发送异步HTTP请求。然而,由于浏览器的同源策略...
Ext.grid.GridPanel 是一个功能强大且广泛使用的Grid控件,但是它存在一个很大的缺陷:单元格的内容不能选中,没法选中就没法复制,这给用户带来了很多不便。这个问题的根源在于ExtJs输出的代码中,每个单元格的div...
在Ext JS这个强大的JavaScript框架中,`Ext.Window`是一个常用组件,用于创建浮动、可弹出的窗口。在Web应用程序中,我们常常需要在这些窗口中展示各种内容,包括文字、表格、按钮,当然还有图片。本文将详细介绍...
2、Ext.ux.grid.feature.Tileview 3、Ext.ux.upload.Button 4、Ext.ux.toggleslide.ToggleSlide 5、Ext.ux.container.ButtonSegment 6、Ext.ux.grid.plugin.RowEditing 7、Ext.ux.grid.plugin.DragSelector 8、Ext....
org.restlet.ext.spring.jar