在jqGrid处理之前如何更改从服务器接收的数据 [英] How to alter data received from the server before processing by jqGrid

查看:603
本文介绍了在jqGrid处理之前如何更改从服务器接收的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要实现的目标的场景:

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

我如何实现这一目标:

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

I made a jqGrid with loadonce:true, editurl:'clientArray' and inline editing. In loadComplete I loop through the data received from the server and add some values. An external button is used to get the grid data using .jqGrid('getGridParam','data') and send it to the server.

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一起工作).我在文档中找不到其他合适的事件.

Problem: The loadComplete event fires when the user changes the grid page or does a search. Which results in overriding any data edited by the him. I tried using the beforeProcessing event instead but it never fires ( It didn't work when testing with local data, but works with loadonce). I could not find any other suitable event in the documentation.

我在演示中复制了该场景.

I reproduced the scenario in this demo.

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

Question: How should I correctly modify the data after receiving it from the server and let the user edit locally, without overriding his edits when he changes the page or does a search?

注意:我正在使用free-jqGrid 4.14

推荐答案

一个人应该使用beforeProcessing而不是loadComplete对从服务器加载的数据进行一些修改.在loadonce: true方案中,该回调非常实用,因为从服务器加载数据后,该回调将仅被调用一次.

One should use beforeProcessing instead of loadComplete to make some modification in the data loaded from the server. The callback is very practical in loadonce: true scenario because it will be called only once after loading the data from the server.

非常重要的一点是,应该减少HTML页面DOM上的更改次数.如果您在通过HTML解析器处理之前更改数据,则它可以非常快速地工作:您更改了一个属性,仅该属性将被更改.另一方面,更改HTML页面上的一个元素会重新计算,并且可能还会更改页面上现有的 all 其他元素.例如,您在网格上插入一个元素.然后,网格的位置(以及网格的所有其他元素)将发生变化.至少Web浏览器必须验证是否需要对 all 现有元素进行某些更改.它是浏览器重排.您可以在循环中更改HTML元素(例如在loadComplete内部调用setRowData),然后从根本上降低HTML页面的速度.

It's very important to understand that one should try to reduce the number of changes on DOM of HTML page. If you change the data before processing by HTML parser then it works very quickly: you change one property and only the property will be changed. On the other side, changing one element on HTML page follows recalculation and probably the changes of all other elements existing on the page. For example you insert an element over the grid. Then the position of the grid (and thus all other elements of the grid) will be changes. At least web browser have to verify whether some changes of all existing elements required. It's browser reflow. It you makes changes of HTML element in the loop (like the call of setRowData inside of loadComplete) then it essentially reduce the speed of the HTML page.

再说一遍.我建议您使用JSFiddle的Echo服务(请参见此处)来模拟加载来自服务器的数据.相应的代码可能如下:

One more remark. I'd recommend you to use Echo service of JSFiddle (see here) to simulate loading of data from the server. The corresponding code could be the following:

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回调(请参见 Wiki文章),它有助于在保存本地数据的过程中进行某些转换.例如定义以下回调(请参见

See modified demo https://jsfiddle.net/OlegKi/c09fnaca/8/. I added template: "integer" in the first column only to demonstrate conversion of data to numbers. Free jqGrid supports convertOnSave callback (see the wiki article), which helps to make some kind of conversions during saving the local data. for example defines the following callback (see the lines of code)

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

结果是,第一列中使用的数据将转换为数字,而不是将数据保存为字符串.

as the result the data used in the first column will be converted to number instead of holding the data as strings.

这篇关于在jqGrid处理之前如何更改从服务器接收的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆