【问题标题】:How to alter data received from the server before processing by jqGrid如何在 jqGrid 处理之前更改从服务器接收到的数据
【发布时间】:2017-10-30 18:01:00
【问题描述】:

我想要实现的场景:

  • 我从服务器检索一些数据
  • 我循环数据并为某些字段添加/更改值
  • 数据正在网格中显示
  • 用户在本地编辑数据
  • 完成后,用户将整个网格数据提交到服务器

我是如何做到的:

我用loadonce:trueediturl:'clientArray' 和内联编辑制作了一个 jqGrid。在loadComplete 中,我遍历从服务器接收到的数据并添加一些值。外部按钮用于使用.jqGrid('getGridParam','data') 获取网格数据并将其发送到服务器。

loadComplete: function(data){
    for(var i=0; i<data.rows.length; i++){
      var row = data.rows[i];
      grid.jqGrid('setRowData', row.id, {
        missingData: 'someDefaultValue'
      });
    }
}

问题:loadComplete 事件在用户更改网格页面或进行搜索时触发。这导致覆盖他编辑的任何数据。我尝试改用beforeProcessing 事件,但它永远不会触发(编辑:在使用本地数据进行测试时它不起作用,但适用于 loadonce)。我在documentation 中找不到任何其他合适的活动。

我在this演示中重现了场景。

问题:我应该如何在从服务器接收到数据后正确地修改数据并让用户在本地编辑,而不会在他更改页面或进行搜索时覆盖他的编辑?

注意:我使用的是 free-jqGrid 4.14

【问题讨论】:

    标签: jquery jqgrid free-jqgrid


    【解决方案1】:

    应该使用beforeProcessing 而不是loadComplete 对从服务器加载的数据进行一些修改。该回调在loadonce: true场景下非常实用,因为它只会在从服务器加载数据后调用一次。

    理解应该尽量减少 HTML 页面的 DOM 上的更改次数,这一点非常重要。如果您在 HTML 解析器处理之前更改数据,那么它会非常快速地工作:您更改一个属性,并且只会更改该属性。另一方面,更改 HTML 页面上的一个元素会遵循重新计算,并且可能会更改页面上存在的 all 其他元素。例如,您在网格上插入一个元素。然后网格的位置(以及网格的所有其他元素)将发生变化。至少网络浏览器必须验证是否需要对 all 现有元素进行某些更改。这是browser reflow。如果您在循环中更改 HTML 元素(例如在 loadComplete 中调用 setRowData),那么它实际上会降低 HTML 页面的速度。

    再说一句。我建议您使用 JSFiddle 的 Echo 服务(请参阅here)来模拟从服务器加载数据。对应的代码如下:

    var i, data = [], grid = $('#grid');
    
    for(i=0; i<4; i++) {
        data.push({id:i, select1: i%3});
    }
    
    grid.jqGrid({
        datatype: "json",
        mtype: "POST",
        url: "/echo/json/",
        postData: {
            json: JSON.stringify(data)
        },
        loadonce: true,
        forceClientSorting: true,
        caption: 'Testing',
        editurl: 'clientArray',
        rowNum: 2,
        rowList: [2, 4],
        pager: true,
        colModel: [
            {name:'select1', label: 'Server status', editable:true, edittype:'select', formatter:'select', template: "integer", editoptions:{
                value:'0:AAA;1:BBB;2:CCC'
            }},
            {name:'select2', label: 'Local status', editable: true, edittype: 'select', formatter:'select', editoptions:{
                value:'0:AAA;1:BBB;2:CCC'
            }},
            {name:'act', template:'actions'}
        ],
        inlineEditing: {
            keys: true
        },
        beforeProcessing: function(data){
            var i;
            for(i=0; i<data.length; i++){
                data[i].select2 = 0;
            }
        }
    });
    
    $('#b1').click(function(){
        $('#out').empty()
        var i, gridData = grid.jqGrid('getGridParam','data');
        for(i=0; i<gridData.length; i++){
           out(JSON.stringify(gridData[i]));
        }
    });
    
    function out(message){
        $('#out').append('<p>' + message +'</p>');
    }
    

    查看修改后的演示 https://jsfiddle.net/OlegKi/c09fnaca/8/。我在第一列中添加了template: "integer",只是为了演示将数据转换为数字。免费 jqGrid 支持convertOnSave 回调(请参阅the wiki article),这有助于在保存本地数据期间进行某种类型的转换。例如定义如下回调(见the lines的代码)

    convertOnSave: function (options) {
        var nData = options.newValue;
        return isNaN(nData) ? nData : parseInt(nData, 10);
    }
    

    因此,第一列中使用的数据将被转换为数字,而不是将数据保存为字符串。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-02
      • 2012-10-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多