【问题标题】:jqGrid - Parsing json responsejqGrid - 解析 json 响应
【发布时间】:2013-04-12 02:58:25
【问题描述】:

我有一个 jqGrid,它将 ajax 请求发送到我的服务器。但是,我的服务器以完全不同的格式发送 json 响应(我无法更改它)。因此我需要解析来自服务器的响应,以便我的 jqGrid 可以正确显示数据。

如果我理解正确,我可以将 ajaxGridOptionsconverters 一起使用。所以,我可以捕获响应并解析它。在我看来,转换器工作正常并正确解析响应。但是,jqGrid 不理解我解析的响应。它永远显示一条消息“正在加载...”(我可以在 firebug 中看到请求/响应很好,并且控制台中没有 javascript 错误)。

谁能帮我解决这个问题?

这是我的代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
    <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/themes/redmond/jquery-ui.css" />
    <link rel="stylesheet" type="text/css" href="http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-4.1.2/css/ui.jqgrid.css" />
</head><body>

<!-- IMPORT JS -->  
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js"></script>
    <script type="text/javascript" src="http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-4.1.2/js/i18n/grid.locale-en.js"></script>
    <script type="text/javascript" src="http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-4.1.2/js/jquery.jqGrid.min.js"></script>    

<script>

$(document).ready(function() {
    var parsedResponse = '{"currentPage" : "1", "totalRecords" : 5, "pageSize" : 3,'
            + '"myData" :[{"id" : "1", "name" : "Name 1" },'
            + '          { "id" : "3", "name" : "Name 3" },'
            + '          { "id" : "2", "name" : "Name 2" }]'
            + '}';

    var myGrid = $('<table>').attr( "id", "useraccount-search-datagrid");
    var myPager = $("<div>").attr("id", "useraccount-search-datagrid-pager");

    $("body").append(myGrid, myPager);

    myGrid.jqGrid({
        pager : myPager,
        // datastr: parsedResponse, // If I use these parameters and remove ajaxGridOptions then it will work fine with the local data
        // datatype : "jsonstring", // If I use these parameters and remove ajaxGridOptions then it will work fine with the local data
        serializeGridData : function(data) {
            return '{"SearchCriteria": {"keyword":"emai","orderByField":"userName","sortOrder":"DESC","pagination":{"pageSize":"10","pageNumber":"2"}}}';
        },
        ajaxGridOptions: {
            url: "../rush-controller-testing/userAccount/find",
            type: "POST",
            contentType: "application/json; charset=utf-8",         
            dataType: "json",
            converters: { "text json": function (responseText) {
                    // console.log(responseText); // Shows the response string from the cerver
                    return parsedResponse;
                }
            },
            success: function(data, textStatus, jqXHR ) {
                // Nice! It shows 'parsedResponse' from 'converters'. Looks good so far.
                console.log(data); console.log(textStatus); console.log(jqXHR);
            }
        },
        colModel : [
            { name : 'name', index : 'id', width : "500"}
        ],
        jsonReader: {
            root: "myData", page: "currentPage", records: "totalRecords" 
        },
        rowNum : 3,
        viewrecords : true,
        height : "auto",
        ignoreCase : true,
        hidegrid: false
    });

}); 
</script>
</body>
</html>

=== 更新 ===

我的服务器响应类似于:

{"UserAccountSearchResult":{
    "userAccounts":[{
        "userAccountId":18,
        "clientAccount":{"clientAccountId":19,"name":"name:5791","firstName":"firstName:5791","lastName":"lastName:5791","active":true},
        "userName":"email@824504.com",
        "password":"password824504",
        "firstName":"firstName824504",
        "lastName":"lastName824504",
        "isActive":true,
        "phoneNumbers":{"phoneNumberId":36,"number":824504824504},
        "addresses":{"addressId":126,"country":"CANADA","provinceOrState":"ONTARIO","address":"address824504","city":"Windsor","postalCode":"postalCode824504"},
        "emails":{"emailId":36,"email":"secondaryEmail@824504.ca"}
        },{
        "userAccountId":44,
        "clientAccount":{"clientAccountId":45,"name":"name:3136","firstName":"firstName:3136","lastName":"lastName:3136","active":true},
        "userName":"email@796312.com",
        "password":"password796312",
        "firstName":"firstName796312",
        "lastName":"lastName796312",
        "isActive":true,
        "phoneNumbers":{"phoneNumberId":88,"number":796312796312},
        "addresses":{"addressId":298,"country":"CANADA","provinceOrState":"ONTARIO","address":"address796312","city":"Greater Sudbury","postalCode":"postalCode796312"},
        "emails":{"emailId":88,"email":"secondaryEmail@796312.ca"}
        }]
    ,"pagination":{"pageSize":10,"pageNumber":2,"totalItems":49}}}

所以,我已经有了一个函数来解析这个响应,如下所示。我想将此解析后的响应与 jqGrid 一起使用,因为在我的应用程序中有很多这样的情况:

{"currentPage" : "1",   "totalRecords" : 2, "pageSize" : 3,
    "myData" :[{
        "id" : "1", "name" : "firstName824504", "email" : "secondaryEmail@824504.ca"
    },{
        "id" : "3", "name" : "firstName796312", "email" : "secondaryEmail@796312.ca"
    }]
};

=== 最终代码 ===

我让它工作了。谢谢您的帮助。这是我的功能示例。我希望它可以在未来对其他人有所帮助。

$(document).ready(function() {
    /*
     * Here I will have a very complex logic to parse the response from the server in something jqGrid can understand.
     * Right now it is just a hard-coded string to make thinks easer to understand
     */ 
    function parseResponse(responseText){
        var parsedResponse = '{"currentPage" : "1", "totalRecords" : 5, "pageSize" : 3, "pageTotal" : 2,'
                + '"myData" :[{"id" : "1", "name" : "Name 1" },'
                + '          { "id" : "3", "name" : "Name 3" },'
                + '          { "id" : "2", "name" : "Name 2" }]'
                + '}';  
        return JSON.parse(parsedResponse);
    };

    var myGrid = $('<table>').attr( "id", "useraccount-search-datagrid");
    var myPager = $("<div>").attr("id", "useraccount-search-datagrid-pager");

    $("body").append(myGrid, myPager);

    myGrid.jqGrid({
        pager : myPager,
        // datastr: parsedResponse, // If I use these parameters and remove ajaxGridOptions then it will work fine with the local data
        datatype : "json",
        url: "../rush-controller-testing/userAccount/find",
        mtype: "POST",
        serializeGridData : function(data) {
            // That is just a hard-coded example to make things easier to understand. Will change it to a more complex logic later.
            return '{"SearchCriteria": {"keyword":"emai","orderByField":"userName","sortOrder":"DESC","pagination":{"pageSize":"10","pageNumber":"3"}}}';
        },
        ajaxGridOptions: {
            contentType: "application/json; charset=utf-8",
        },
        colModel : [
            { name : 'name', index : 'name', width : "500"}
        ],
        jsonReader: {
            repeatitems: false,
            root: function(data){
                //the actual data
                var result = parseResponse(data);
                return result.myData;
            },
            total: function(data) {
                //total pages for the query
                var result = parseResponse(data);
                return result.pageTotal;
            },
            page: function(data){
                //current page of the query
                var result = parseResponse(data);
                return result.currentPage;
            },
            records: function(data){
                //total number of records for the query
                var result = parseResponse(data);
                return result.totalRecords;
            } 
        },
        rowNum : 3,
        viewrecords : true,
        height : "auto",
        ignoreCase : true,
        hidegrid: false
    });

});

【问题讨论】:

  • 服务器发回的这种“奇怪的格式”是什么?
  • 这不是错误,只是从服务器发回的响应(JSON 格式),我必须解析。

标签: jquery jquery-plugins jqgrid


【解决方案1】:

您以错误的方式使用 jqGrid 选项。重要的是要了解 jqGrid 需要“知道”一些参数,例如 urldatatype。如果未指定datatype,则将使用默认值"xml"

您不应覆盖 jqGrid 中已存在的 ajaxGridOptions 参数。所以你应该正确使用jqGrid。如果 URL "../rush-controller-testing/userAccount/find" 以您包含在 parsedResponse 中的格式返回数据,那么您的代码可能如下所示:

myGrid.jqGrid({
    url: "../rush-controller-testing/userAccount/find",
    datatype: "json",
    mtype: "POST",
    pager: "#useraccount-search-datagrid-pager",
    serializeGridData : function(data) {
        // the function is DUMMY. it MUST be replaced
        return '{"SearchCriteria": {"keyword":"emai","orderByField":"userName","sortOrder":"DESC","pagination":{"pageSize":"10","pageNumber":"2"}}}';
    },
    ajaxGridOptions: { contentType: "application/json; charset=utf-8" },
    colModel: [
        { name: 'id', key: true, width: 100 }
        { name: 'name', width: 400 }
    ],
    jsonReader: {
        root: "myData",
        page: "currentPage",
        records: "totalRecords",
        repeatitems: false
    },
    rowNum: 3,
    gridview: true,
    autoencode: true,
    viewrecords: true,
    height: "auto",
    ignoreCase: true,
    hidegrid: false
});

jsonReader 内部使用repeatitems: false 属性确实是必需的。我认为您不需要使用任何 converters 的 jQuery.ajax。

【讨论】:

  • 非常感谢您的详细回答。我将尝试这些更改并尽快通知您。 (顺便说一句,您在 stackoverflow 上写了许多其他好的答案,感谢您的贡献)。
  • @YoriKusanagi:不客气!我很高兴我的旧答案也可以帮助你。顺便说一句,在许多情况下,可以使用prmNames 选项来自定义将发送到服务器的参数。 serializeGridData只是信息转化的最后一步。
  • 此时,我真正的挑战是解析来自服务器的响应。我已经为此工作了好几个小时,但无法弄清楚出了什么问题。任何帮助将不胜感激。
  • @YoriKusanagi:对不起,我不明白这个。 jQuery.ajax 自动 解析 JSON 响应,它使用大多数 Web 浏览器使用 本机实现 的代码。所以不需要手动解析服务器响应。
  • 如果我的帖子不清楚,我深表歉意。我并不是说“解析为 JSON”这很容易实现,我需要将响应解析为完全不同的结构。我刚刚在我的问题中添加了一个响应示例。希望它能让事情变得清晰。
【解决方案2】:

查看 jqGrid wiki 上的 data manipulation pages。我想jsonReader 可能就是你要找的东西。

【讨论】:

  • 我尝试过使用 jsonReader,但在我的情况下它不起作用。从服务器发送的数据非常不同。因此,我需要一个复杂的解析函数来处理它。
猜你喜欢
  • 2013-03-27
  • 1970-01-01
  • 2020-03-04
  • 2019-05-15
  • 2018-12-04
  • 1970-01-01
  • 2012-09-04
相关资源
最近更新 更多