zoukankan      html  css  js  c++  java
  • ExtJs实现刷新Grid单个单元格

    页面上存在定时刷新表格的功能,而且表格中每行又有详情,当每次刷新每行时,即执行了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 = '' + 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", 160, sortable: true,renderer: titleQtip, dataIndex: 'company'},
                {header: "Price", 75, sortable: true, renderer: 'usMoney', dataIndex: 'price'},
                {id:'change',header: "Change", 75, sortable: true, renderer: change, dataIndex: 'change'},
                {header: "% Change", 75, sortable: true, renderer: pctChange, dataIndex: 'pctChange'},
                {header: "Last Updated", 85, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
            ],
            stripeRows: true,
            autoExpandColumn: 'company',
            height:320,
            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');
    }

  • 相关阅读:
    POJ 2251 Dungeon Master
    HDU 3085 Nightmare Ⅱ
    CodeForces 1060 B Maximum Sum of Digits
    HDU 1166 敌兵布阵(树状数组)
    HDOJ 2050 折线分割平面
    HDU 5879 Cure
    HDU 1878 欧拉回路
    HDU 6225 Little Boxes
    ZOJ 2971 Give Me the Number
    HDU 2680 Choose the best route
  • 原文地址:https://www.cnblogs.com/sky7034/p/2142039.html
Copyright © 2011-2022 走看看