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');
    }

  • 相关阅读:
    8.指针小结
    8.指针
    7.数组
    6.结构化程序设计
    python之迭代器
    1.python基础—有这篇文章足够
    python装饰器,细致讲解
    django客户管理系统-使用modelform对HTML标签统一添加样式
    python之md5使用方法
    git干货教程
  • 原文地址:https://www.cnblogs.com/sky7034/p/2142039.html
Copyright © 2011-2022 走看看