背景:
界面有两个GridPanel,分别为发票列表、费用列表。一个必要对应多个费用进行核销。
应用上,选择一个发票记录时,自动加载对应的同一业务下的费用,并计算出总费用金额。将费用总金额回写到选择的发票核销金额字段。
当发票有多行记录时,一切正常。当发票只有一条时,发生死循环。
调试:初步调试发现,如果只有一条发票时,费用加载完自己又清除掉,然后再加载。
查看Ext源代码,发现为Ext2.0的一个bug。在Ext2.2以后都已经解决。
过程:
1,回写发票的核销金额时,调用了Record的set方法。
set : function(name, value){
if(String(this.data[name]) == String(value)){
return;
}
this.dirty = true;
if(!this.modified){
this.modified = {};
}
if(typeof this.modified[name] == 'undefined'){
this.modified[name] = this.data[name];
}
this.data[name] = value;
if(!this.editing && this.store){
this.store.afterEdit(this);
}
}
2,Store的afterEdit方法,触发update事件
// private
afterEdit : function(record){
if(this.modified.indexOf(record) == -1){
this.modified.push(record);
}
this.fireEvent("update", this, record, Ext.data.Record.EDIT);//触发事件,查看相关的监听者,猜测在GridView或GridPanel
},
3,GridView监听了store的update事件,进而触发了onUpdate方法。
而onUpdate直接调用了refreshRow方法。
这里,可以看到当Record改变时,GridView采取的方法是先insertRows再onRemove。最后才触发rowupdated事件。跟踪过rowupdated事件的监听者,未发现异常。
因为是只有一行记录才出现问题,所以需要对数字的判断敏感一些。
当只有一条Record时,在insertRows方法中,实际只是刷新了一下。并没有真正的删除。
接下去就是看refresh方法做什么?
// private
initData : function(ds, cm){
if(this.ds){
//省略……
}
if(ds){
ds.on("load", this.onLoad, this);
ds.on("datachanged", this.onDataChange, this);
ds.on("add", this.onAdd, this);
ds.on("remove", this.onRemove, this);
ds.on("update", this.onUpdate, this);
ds.on("clear", this.onClear, this);
}
this.ds = ds;
//省略....
},
// private
onUpdate : function(ds, record){
this.refreshRow(record);
},
// private
refreshRow : function(record){
var ds = this.ds, index;
if(typeof record == 'number'){
index = record;
record = ds.getAt(index);
}else{
index = ds.indexOf(record);
}
var cls = [];
this.insertRows(ds, index, index, true);
this.getRow(index).rowIndex = index;
this.onRemove(ds, record, index+1, true);
this.fireEvent("rowupdated", this, index, record);
},
insertRows : function(dm, firstRow, lastRow, isUpdate){
if(firstRow === 0 && lastRow == dm.getCount()-1){
this.refresh();
}else{
if(!isUpdate){
this.fireEvent("beforerowsinserted", this, firstRow, lastRow);
}
var html = this.renderRows(firstRow, lastRow);
var before = this.getRow(firstRow);
if(before){
Ext.DomHelper.insertHtml('beforeBegin', before, html);
}else{
Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html);
}
if(!isUpdate){
this.fireEvent("rowsinserted", this, firstRow, lastRow);
this.processRows(firstRow);
}
}
}
4,GridView的refresh触发了refresh事件,进而触发Ext.grid.RowSelectionModel的onRefresh函数。
直接便抛出了选择修改事件。
onRefresh : function(){
var ds = this.grid.store, index;
var s = this.getSelections();
this.clearSelections(true);
for(var i = 0, len = s.length; i < len; i++){
var r = s[i];
if((index = ds.indexOfId(r.id)) != -1){
this.selectRow(index, true);
}
}
if(s.length != this.selections.getCount()){
this.fireEvent("selectionchange", this);
}
}
综合上代码跟踪。第3步中的GridView的insertRows方法调用了refresh()是导致问题所在。则重写此方法解决此问题。
/**
* 解决Grid只有一条数据时,对该记录调用set方法时,会造成刷新/选择事件
*20101125.1 By Simon
*/
Ext.grid.GridView.prototype.insertRows = function(dm, firstRow, lastRow, isUpdate) {
if (!isUpdate && firstRow === 0 && lastRow >= dm.getCount() - 1) {//加入判断是否只是update
this.refresh();
} else {
if (!isUpdate) {
this.fireEvent("beforerowsinserted", this, firstRow, lastRow);
}
var html = this.renderRows(firstRow, lastRow);
var before = this.getRow(firstRow);
if (before) {
Ext.DomHelper.insertHtml('beforeBegin', before, html);
} else {
Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html);
}
if (!isUpdate) {
this.fireEvent("rowsinserted", this, firstRow, lastRow);
this.processRows(firstRow);
}
}
this.syncFocusEl(firstRow);
};
分享到:
相关推荐
9. **Ext Designer支持**:EXT 2.0可能还支持EXT Designer,一个可视化的布局编辑工具,使得非程序员也能创建EXT界面。 10. **主题和皮肤**:EXT提供了多种预设的主题,可以改变整个应用程序的外观和感觉。 11. **...
7. **事件处理**:Ext 2.0使用事件驱动模型,允许组件之间通过触发和监听事件进行通信。开发者可以通过注册事件监听器来响应用户操作或组件状态变化,实现业务逻辑。 8. **AJAX支持**:Ext 2.0内置了AJAX功能,可以...
8. **强大的表格功能**:EXT 2.0的GridPanel组件支持分页、排序、过滤、编辑等功能,可以处理大量数据并提供高效的显示和操作。 9. **拖放支持**:EXT 2.0支持组件之间的拖放操作,可以用于构建交互式的应用,如...
4. **表单处理**:EXT2.0提供了强大的表单处理功能,包括字段验证、数据绑定和远程提交等。 5. **图表组件**:EXT2.0支持多种图表类型,如柱状图、饼图、线图等,用于数据可视化。 6. **拖放功能**:EXT2.0支持...
5. **分页和数据加载**:EXT2.0的GridPanel支持分页,你将看到如何配置和使用PagingToolbar来实现分页功能,以及如何在用户翻页时动态加载数据。 6. **自定义行为**:EXT GridPanel允许开发者自定义很多行为,例如...
3. **表格网格**:Ext 2.0的表格组件(GridPanel)功能强大,支持分页、排序、过滤、编辑等功能,能处理大量数据并实现高性能渲染。同时,它还提供了行选择、行编辑等多种交互模式。 4. **表单组件**:Ext 2.0提供...
7. **丰富的图表组件**:EXT2.0提供了一系列图表组件,如柱状图、饼图、线图等,用于数据可视化。 **EXT2.0 API** EXT2.0的API是其强大的基础,它包含了大量预定义的类和方法,供开发者在构建应用时调用。API分为...
EXT2.0帮助文档CHM版是为EXT框架开发者提供的一款详尽的API参考手册,以方便用户理解和使用EXT库的各个组件和功能。EXT是一个流行的JavaScript库,主要用于构建富客户端Web应用程序,它提供了丰富的用户界面组件和...
EXT2.0是EXT JavaScript库的一个早期版本,它是一个强大的前端开发框架,尤其适用于构建复杂的、数据驱动的Web应用程序。EXT2.0的核心是它的组件模型,它提供了一系列丰富的用户界面组件,如表格、面板、窗口、菜单...
### Ext2.0框架的Grid使用介绍 #### 一、Ext2.0框架概述 Ext2.0是一款基于JavaScript的库,它提供了大量的用户界面组件,使得开发人员能够轻松地构建出高度交互式的Web应用程序。相比其他框架如YUI等,Ext2.0拥有...
在 `newtpanel.aspx` 文件中,可能会使用 `XTemplate` 或 `ClientScript` 来在客户端执行JavaScript代码,以便在特定事件(如按钮点击)时动态显示或隐藏GridPanel。 3. **配置数据源**: GridPanel的数据源可以...
2. **易于使用的API**:Ext 2.0的API设计友好,易于理解,即使是初学者也能快速上手。 3. **高度可定制**:通过CSS和模板系统,开发者可以根据需求定制界面样式。 4. **优秀的文档和支持**:官方提供了详尽的文档和...
Ext2.0 是一个强大的JavaScript框架,特别适用于构建富客户端应用程序,尤其是复杂的Web界面。它的核心特性在于提供了一系列丰富的组件,包括Grid(表格)控件,这使得开发者能够用JS创建出与桌面应用相当的交互体验...
EXT2.0中文教程主要涵盖了EXT JavaScript库的深入学习与实践,这个库是Sencha公司开发的一个强大的前端用户界面框架,特别适用于构建富互联网应用程序(RIA)。EXT2.0不仅提供了丰富的组件库,还拥有强大的数据绑定...
### Ext2.0框架的Grid使用详解 #### 引言 在前端开发领域,Ext2.0框架以其强大的功能和灵活的组件库而备受推崇,尤其是其Grid组件,更是前端开发者构建美观、交互性强的数据展示界面的利器。本文将深入探讨Ext2.0...
EXT 2.0 API 是一个用于构建富互联网应用程序(Rich Internet Applications, RIA)的JavaScript框架,它在前端开发领域中扮演着重要角色。EXT 2.0 提供了一套全面且强大的组件库,使开发者能够创建功能丰富的、交互...
EXT2.0分页是网页开发中的一种常见技术,它主要应用于大数据量的展示场景,如搜索结果、用户列表或论坛帖子等。在EXT2.0框架中,分页功能是为了提高网页性能和用户体验而设计的。EXT2.0是一个基于JavaScript的富...
"ext gridpanel 跨行"这个主题主要涉及到在GridPanel中实现单元格或行的跨行显示,这在展示复杂数据或需要组合信息时非常有用。 首先,让我们深入理解什么是GridPanel。在Ext JS中,GridPanel是一个表格视图,它...
在提供的代码段中,我们看到一个监听`cellclick`事件的例子,这是EXT GridPanel中用于捕获用户点击单元格时的事件。下面是这段代码的详细解释: 1. `cellclick`: 这是EXT GridPanel的事件名,当用户点击表格内的...
对于GridPanel中拖动选中行排序的实现,网上有不少ExtJs实现的例子,但是没有找到使用Ext.net实现的,正好最近有个需求要使用,干脆来写一个。 DEMO功能说明: 1、拖动GridPanel选中行到新位置排序。 2、在拖动结束...