`

ExtJs实现刷新Grid单个单元格

 
阅读更多

产生问题背景:

ExtJS3.2版本

页面上存在定时刷新表格的功能,而且表格中每行又有详情,当每次刷新每行时,即执行了Record的Set方法,详情都会关闭。刚开始觉得很奇怪。因为我一直觉得,我刷新一行中的一个字段的话,那应该是只更新这个字段的DOM就行了。

 

后台查看了一下源代码原来,每个Record数据变化时,其实都是重新生成一条新行的DOM。在源代码的执行步骤是,先新插入一行,再把旧数据的行DOM删除换。

 

由于详情是属于行的,所以,每次执行Record的Set后,行重新生成,那么详情肯定会删除掉。

 

为了解决详情不关闭这个问题,我们想方法为Record自定义一个Replace方法出来。

 

它的功能是:使用Record的Replace方法,可以实现单个字段的更新。

 

看起来很空间的一句话,可是为了实现这个功能,重写了ExtJs很多的“类”才实现了。下面是为了实现这个功能代码,

 

还带了实现了一个功能,使用ExtJs提供的冒泡提示加到表格的字段值中。

Ext.onReady(function(){
	//要使用ExtJS提供的冒泡提示,必须加上下面这句
	Ext.QuickTips.init();
	Ext.override(Ext.grid.ColumnModel,{
		//根据列定义时的给出的ID,得到该列的渲染方法,其实是为了更新单个单元格时,显示与定义一致
		getRendererById:function(id){
			return this.getRenderer(this.getIndexById(id));
		}
	});
	//步骤4:
	Ext.data.Record.REPLACE = 'repalce';//定义一个记录的替换命令,目前没有什么作用
	Ext.override(Ext.data.Record,{
			//替换单个字段的值的方法
			replace : function(name, value){
				var encode = Ext.isPrimitive(value) ? String : Ext.encode;
				if(encode(this.data[name]) == encode(value)) {
					return;
				}        
				this.dirty = true;
				if(!this.modified){
					this.modified = {};
				}
				if(this.modified[name] === undefined){
					this.modified[name] = this.data[name];
				}
				this.data[name] = value;//模型更新
				this.afterReplace(name,value);//通过Store通知gridview视图更新
			},
			//通过Store通知gridview视图更新方法
			afterReplace:function(name,value){
				 if (this.store != undefined && typeof this.store.afterReplace == "function") {
					this.store.afterReplace(this,name,value);
				}
			}
    });
	//步骤5:
	Ext.override(Ext.data.Store,{
				//新定义的通知gridview视图更新的方法
			    afterReplace : function(record,name,value){
					if(this.modified.indexOf(record) == -1){
						this.modified.push(record);
					}
					//通知视图更新
					this.fireEvent('repalce',record,name,value, Ext.data.Record.REPLACE);
				}
		}
	);
    var myData = [
        ['3m Co',71.72,0.02,0.03,'9/1 12:00am'],
        ['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am'],
        ['Altria Group Inc',83.81,0.28,0.34,'9/1 12:00am']
    ];

    // example of custom renderer function
    function change(val){
        if(val > 0){
            return '<span qtip="'+val+'" style="color:green;">' + val + '</span>';
        }else if(val < 0){
            return '<span qtip="'+val+'" style="color:red;">' + val + '</span>';
        }
        return val;
    }
	//使用ExtJS提供的冒泡提示
	function titleQtip(val){
		return '<span qtip="'+val+'">' + val + '</span>';
	}
    // example of custom renderer function
    function pctChange(val){
        if(val > 0){
            return '<span style="color:green;">' + val + '%</span>';
        }else if(val < 0){
            return '<span style="color:red;">' + val + '%</span>';
        }
        return val;
    }

    // create the data store
    var store = new Ext.data.Store({
        proxy: new Ext.ux.data.PagingMemoryProxy(myData),
        remoteSort:true,
        sortInfo: {field:'price', direction:'ASC'},
        reader: new Ext.data.ArrayReader({
            fields: [
               {name: 'company'},
               {name: 'price', type: 'float'},
               {name: 'change', type: 'float'},
               {name: 'pctChange', type: 'float'},
               {name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'}
            ]
        })
    });
	Ext.override(Ext.grid.GridView,{
			////步骤7:真正实现GridView更新单个单元格的方法
			onReplace:function(record,name,value){
				 var ds = this.ds, index;
				if(Ext.isNumber(record)){
					index = record;
					record = ds.getAt(index);
					if(!record){
						return;
					}
				}else{
					index = ds.indexOf(record);
					if(index < 0){
						return;
					}
				}
				//实现单个字段的更新
				document.getElementById(index+name).innerHTML = this.cm.getRendererById(name).call(this,value);
		},
		//步骤6:
	initData : function(ds, cm){
        if(this.ds){
            this.ds.un('load', this.onLoad, this);
            this.ds.un('datachanged', this.onDataChange, this);
            this.ds.un('add', this.onAdd, this);
            this.ds.un('remove', this.onRemove, this);
            this.ds.un('update', this.onUpdate, this);
            this.ds.un('clear', this.onClear, this);
			//表格销毁时把这个监听放弃
			this.ds.un('repalce', this.onReplace, this);
            if(this.ds !== ds && this.ds.autoDestroy){
                this.ds.destroy();
            }
        }
        if(ds){
            ds.on({
                scope: this,
                load: this.onLoad,
                datachanged: this.onDataChange,
                add: this.onAdd,
                remove: this.onRemove,
                update: this.onUpdate,
                clear: this.onClear,
				//当表格加载Store时,把这个监听添加上
				repalce: this.onReplace
            });
        }
        this.ds = ds;

        if(this.cm){
            this.cm.un('configchange', this.onColConfigChange, this);
            this.cm.un('widthchange', this.onColWidthChange, this);
            this.cm.un('headerchange', this.onHeaderChange, this);
            this.cm.un('hiddenchange', this.onHiddenChange, this);
            this.cm.un('columnmoved', this.onColumnMove, this);
        }
        if(cm){
            delete this.lastViewWidth;
            cm.on({
                scope: this,
                configchange: this.onColConfigChange,
                widthchange: this.onColWidthChange,
                headerchange: this.onHeaderChange,
                hiddenchange: this.onHiddenChange,
                columnmoved: this.onColumnMove
            });
        }
        this.cm = cm;
    },
		doRender : function(columns, records, store, startRow, colCount, stripe) {
        var templates    = this.templates,
            cellTemplate = templates.cell,
            rowTemplate  = templates.row,
            last         = colCount - 1;

        var tstyle = 'width:' + this.getTotalWidth() + ';';

        // buffers
        var rowBuffer = [],
            colBuffer = [],
            rowParams = {tstyle: tstyle},
            meta      = {},
            column,
            record;

        //build up each row's HTML
        for (var j = 0, len = records.length; j < len; j++) {
            record    = records[j];
            colBuffer = [];

            var rowIndex = j + startRow;

            //build up each column's HTML
            for (var i = 0; i < colCount; i++) {
                column = columns[i];
                meta.id    = column.id;
                meta.css   = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
                meta.attr  = meta.cellAttr = '';
                meta.style = column.style;
                meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);
				//步骤2:定义这个字段的DIV的ID,这个地方是关键,否则我们通过document.getElementById找不到这个DIV,也就不可以实现这个功能了。
				meta.divId = j+column.name;
                if (Ext.isEmpty(meta.value)) {
                    meta.value = '&#160;';
                }
                if (this.markDirty && record.dirty && Ext.isDefined(record.modified[column.name])) {
                    meta.css += ' x-grid3-dirty-cell';
                }

                colBuffer[colBuffer.length] = cellTemplate.apply(meta);
            }

            //set up row striping and row dirtiness CSS classes
            var alt = [];
            if (stripe && ((rowIndex + 1) % 2 === 0)) {
                alt[0] = 'x-grid3-row-alt';
            }
            if (record.dirty) {
                alt[1] = ' x-grid3-dirty-row';
            }

            rowParams.cols = colCount;

            if (this.getRowClass) {
                alt[2] = this.getRowClass(record, rowIndex, rowParams, store);
            }

            rowParams.alt   = alt.join(' ');
            rowParams.cells = colBuffer.join('');

            rowBuffer[rowBuffer.length] = rowTemplate.apply(rowParams);
        }

        return rowBuffer.join('');
    }
	});
	var ts = {};
	ts.cell = new Ext.Template('<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>',
	//步骤1:本来是打开在GridView重写这部分,可是发现代码太多,觉得没有必要,在这里直接定义为Div添加一个id的属性即可。
	'<div  id=\'{divId}\' class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>','</td>');
    // create the Grid
    var grid = new Ext.grid.GridPanel({
        store: store,
		//步骤3:注意在添加这个属性
		viewConfig:{
			templates:ts
		},
        columns: [
            {id:'company',header: "Company", width: 160, sortable: true,renderer: titleQtip, dataIndex: 'company'},
            {header: "Price", width: 75, sortable: true, renderer: 'usMoney', dataIndex: 'price'},
            {id:'change',header: "Change", width: 75, sortable: true, renderer: change, dataIndex: 'change'},
            {header: "% Change", width: 75, sortable: true, renderer: pctChange, dataIndex: 'pctChange'},
            {header: "Last Updated", width: 85, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
        ],
        stripeRows: true,
        autoExpandColumn: 'company',
        height:320,
        width:600,
        frame:true,
        title:'Sliding Pager',
		id:'maingrid',
        plugins: new Ext.ux.PanelResizer({
            minHeight: 100
        }),

        bbar: new Ext.PagingToolbar({
            pageSize: 10,
            store: store,
            displayInfo: true
        })
    });
	
    grid.render('grid-example');
	
    store.load({params:{start:0, limit:10}});
	
	

	
	//alert(document.getElementById('1pctChange').innerHTML);
});
//测试该功能的代码
function change(){
	//修改第2行的company这个字段的值
	Ext.getCmp('maingrid').store.getAt(1).replace('company','ddddd');
}

 

 

 

 

 

 

 

0
2
分享到:
评论
2 楼 lyndon.lin 2011-11-03  
ExtJs自带表格更新更新功能,更新一行,我写的这个是只更新一行中的某个字段。
1 楼 bing_zz 2011-10-28  
不怎么详细,猜来猜去还是不知道要实现的是什么,可不可以把你实现后截个图。
看来我的道行不够,也不知道此文是否能够解决我的问题,只有一个核心代码,还原实现时间太紧带风险。
lyndon.lin辛苦了。

相关推荐

    Ext grid合并单元格

    根据提供的文件信息,我们可以深入探讨如何在 Ext JS 中实现 Grid 的单元格合并功能。此案例主要涉及到了自定义 GridView 的 `renderHeaders` 方法来达到单元格合并的目的,并且还涉及了模板(Template)的使用、...

    ExtJS GRID单元格合并

    下面我们将深入探讨如何在ExtJS 4.0 Grid中实现单元格合并,以及其背后的技术细节。 首先,理解Grid的基本结构是关键。Grid由一系列行(rows)和列(columns)组成,每个单元格(cell)对应一个特定的数据值。在...

    ExtJS 4.2 Grid组件单元格合并的方法

    ExtJS 4.2 Grid组件本身并没有提供单元格合并功能,需要自己实现这个功能。 目录 1. 原理 2. 多列合并 3. 代码与在线演示 1. 原理 1.1 HTML代码分析 首先创建一个Grid组件,然后查看下的HTML源码。 1.1.1 Grid组件 ...

    grid 合并单元格示例

    实现grid单元格重复数据的合并,完整的案例实现,包含合并方法和调用过程

    extjs单元格无法复制

    解决 ExtJS GridPanel 单元格无法选中复制的问题需要两个步骤:添加新的 CSS 样式和修改 Ext.grid.GridPanel 的 prototype。通过这些步骤,我们可以使得单元格的内容可以被选中和复制,从而提高用户体验。

    ExtJs动态grid的生成

    我们首先从标题"ExtJs动态grid的生成"开始,了解动态生成Grid的基本概念和实现方法。 动态生成Grid意味着在运行时根据需求创建和更新Grid组件,而不是在应用初始化时静态定义。这种灵活性允许开发者更好地响应数据...

    Extjs 合并单元格

    标题中的“Extjs 合并单元格”指的是在Ext JS框架下实现表格(Grid)中单元格的合并功能。Ext JS是一个强大的JavaScript库,专用于构建富客户端Web应用,其核心组件之一就是数据网格(Data Grid),用于展示大量结构...

    ExtJS grid过滤操作

    ExtJS Grid是一个强大的数据展示组件,它允许用户以表格的形式查看和操作大量数据。在实际应用中,数据过滤是常见的需求,以便用户能快速定位到感兴趣的信息。本篇将深入探讨ExtJS Grid的过滤操作,以及如何动态地对...

    EXTJS单元格变色、行变色

    EXTJS单元格变色、行变色实现方法详解 EXTJS是一个功能强大且流行的JavaScript框架,用于构建复杂的Web应用程序。其中,Grid Panel是EXTJS中最常用的组件之一,用于展示和编辑数据。本文将详细介绍EXTJS实现单元格...

    Extjs4下拉菜单ComboBox中用Grid显示通用控件

    在EXTJS4中,`ComboBox` 是一个非常常用的组件,它提供了一个下拉选择框的功能。在某些场景下,我们可能需要在下拉菜单中展示更丰富的信息,比如表格数据,这时...在EXTJS4中,这个控件是实现复杂下拉选择功能的利器。

    extjs4打印grid插件

    在ExtJS4中,有时我们需要实现打印Grid的功能,以便用户能够将屏幕上的数据显示在纸质或PDF文档上。这就是"extjs4打印grid插件"的作用。 打印Grid插件是为了满足这种需求而设计的,它允许开发者扩展ExtJS4 Grid ...

    extjs中设置grid默认行高及换行

    Extjs 中想改变grid 行高,如果只是简单的设置了height的值是可以实现grid 的行高,但是如果使用了插件:rowexpander ,最出现新的问题。 感兴趣的朋友可以试试的。 此文档可以解决你的烦恼,为了找到资源下载,...

    extjs合并单元格

    标题中的“extjs合并单元格”指的是在使用Ext JS这个JavaScript框架时,如何实现表格(Grid)中的单元格合并功能。Ext JS是一个用于构建富客户端Web应用的前端框架,提供了丰富的组件库,其中包括数据网格(Data ...

    extjs 04_grid 单击事件新发现

    本篇文章将详细探讨EXTJS Grid中的单击事件处理以及如何获取单元格和行的数据。 在EXTJS的Grid组件中,我们可以监听各种事件,如`cellclick`事件,当用户点击网格的单元格时,此事件会被触发。下面是一个简单的示例...

    Extjs4 Grid分页与自动刷新

    ### Extjs4 Grid分页与自动刷新 #### 一、Extjs4 Grid 分页功能实现 在使用Extjs4进行Web应用开发时,Grid控件是常用的数据展示组件之一。对于大数据量的情况,通常需要使用分页来提高用户体验。下面详细介绍如何...

    extjs grid设置某列背景颜色和字体颜色的实现方法

    下面将详细解释如何在EXTJS Grid中实现这一功能。 首先,我们要理解EXTJS Grid中的`renderer`函数。这个函数是用来格式化和渲染网格单元格的内容。通过定义`renderer`,我们可以自定义单元格的显示方式,包括改变...

    Extjs动态Grid的生成 htm

    Extjs动态Grid的生成 htm

    Extjs Grid2Grid拖拽

    在实现"Extjs Grid2Grid拖拽"时,主要涉及以下几个关键知识点: 1. **ExtJS Grid组件**:首先,你需要熟悉Grid的基本用法,包括创建列模型、数据源(store)、配置项等。Grid可以动态加载数据,支持排序、分页、...

    extjs grid数据导出excel文件

    本文将深入讲解EXTJS Grid如何实现数据导出到Excel文件的功能。 首先,我们要明白EXTJS Grid的数据导出到Excel的过程通常涉及到以下几个步骤: 1. **获取Grid数据**:在EXTJS中,Grid的数据存储在Store对象中。要...

Global site tag (gtag.js) - Google Analytics