如何通过的jqGrid改变处理之前从服务器接收到的数据

问题描述:

情景我想要实现:如何通过的jqGrid改变处理之前从服务器接收到的数据

  • 我从服务器中检索某些数据
  • 我循环中的数据,并添加/改变值的某些字段
  • 的数据被显示在一个网格
  • 用户本地编辑
  • 当完成时,用户提交整个网格数据到所述数据服务器

我怎样努力去实现它:

我做了一个jqGrid的与loadonce:trueediturl:'clientArray'和在线编辑。在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演示中复制了场景。

问题:从服务器接收数据后如何正确修改数据,让用户在本地进行编辑,而不必在更改页面或执行搜索时重写编辑?

注:我使用*的jqGrid 4.14

应该使用beforeProcessing,而不是loadComplete,使从服务器加载的数据做一些修改。该回调在loadonce: true方案中非常实用,因为从服务器加载数据后它只会被调用一次。

理解人们应该尝试减少HTML页面的DOM上的更改数量非常重要。如果您在通过HTML解析器处理之前更改数据,那么它的工作速度非常快:您更改一个属性并且只更改属性。另一方面,更改HTML页面上的一个元素会进行重新计算,并且可能会更改页面上存在的其他元素的所有。例如,你在网格上插入一个元素。那么网格的位置(以及网格的所有其他元素)将会发生变化。至少网络浏览器必须验证是否需要对现有元素进行一些更改全部。这是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); 
} 

作为结果在第一列中所使用的数据将被转换为数字的而不是保持数据为字符串。