【问题标题】:jqGrid does not populate with datajqGrid 不填充数据
【发布时间】:2011-04-24 03:27:29
【问题描述】:

我正在尝试使用来自 Web 服务的数据填充 jqGrid。我已经彻底查看了 jqGrid 代码和文档。我需要另一双眼睛来查看下面的代码并告诉我是否遗漏了什么。

正如您将在代码中看到的,我将网格设置为在页面加载或刷新期间加载。网格加载后,我进行 Ajax 调用以获取 JSON 数据(再次)并显示在网格下方的 div 中。

我看到了大部分预期的行为。页面加载后,网格显示加载指示器,然后启动 Ajax 调用,JSON 数据显示在网格下方。问题是网格完全是空的。列标题正确,但网格正文中未显示任何数据。

代码如下:

$(document).ready(function () {
    $('#resultDiv').html('');
    $('#waitIndicator').hide();
    $("#list").jqGrid({
        datatype: 'json',
        url: 'WeatherDataService.svc/GetWeatherData',
        jsonReader: {
            root: "Rows",
            page: "Page",
            total: "Total",
            records: "Records",
            repeatitems: false,
            userdata: "UserData",
            id: "StationId"
        },
        loadui: "block",
        mtype: 'GET',
        rowNum: 10,
        rowList: [10, 20, 30],
        viewrecords: true,
        colNames: ['Station ID', 'Station Name', 'Timestamp', 'Max Temp',
                   'Min Temp', 'Precipitation', 'Snowfall', 'SnowDepth'],
        colModel: [
            { name: 'StationId', index: 'StationId' },
            { name: 'StationName', index: 'StationName' },
            { name: 'Timestamp', index: 'Timestamp', align: 'right' },
            { name: 'MaxTemperature', index:'MaxTemperature',align:'right'},
            { name: 'MinTemperature', index:'MinTemperature',align:'right'},
            { name: 'Precipitation', index: 'Precipitation', align:'right'},
            { name: 'Snowfall', index: 'Snowfall', align: 'right' },
            { name: 'SnowDepth', index: 'SnowDepth', align: 'right' },
        ],
        pager: '#pager',
        sortname: 'StationId',
        sortorder: 'asc',
        caption: 'Weather Records',
        loadComplete: function () {
            // if the page index is not set (e.g. page index = 0),
            // force the page index to first page
            var pageIndex = $('#list').jqGrid('getGridParam', 'page');
            if (pageIndex == 0) pageIndex = 1;

            $('#waitIndicator').show();
            $.ajax({
                url: 'WeatherDataService.svc/GetWeatherData',
                type: "GET",
                data: ({ page: pageIndex, rows: 10,
                         sidx: 'StationId', sord: 'asc' }),
                dataType: "json",
                success: function (response) {
                    $('#resultDiv').html(response);
                    $('#waitIndicator').hide();
                },
                error: function (xmlHttpRequest, textStatus, errorThrown) {
                    $('#resultDiv').html('textStatus: ' + textStatus + 
                                         ', errorThrown: ' + errorThrown);
                }
            });
        }
    });
}); 

这是来自网络服务的 JSON 数据:

{
    "Total": 14975,
    "Page": 1,
    "Records": 149746,
    "Rows": [
        {
            "StationId": 50130,
            "StationName": "ALAMOSA WSO AP",
            "Timestamp": "\/Date(725871600000)\/",
            "MaxTemperature": null,
            "MinTemperature": null,
            "Precipitation": null,
            "Snowfall": null,
            "SnowDepth": null
        },
        {
            "StationId": 50130,
            "StationName": "ALAMOSA WSO AP",
            "Timestamp": "\/Date(725958000000)\/",
            "MaxTemperature": null,
            "MinTemperature": null,
            "Precipitation": null,
            "Snowfall": null,
            "SnowDepth": null
        },
        {
            "StationId": 50130,
            "StationName": "ALAMOSA WSO AP",
            "Timestamp": "\/Date(726044400000)\/",
            "MaxTemperature": null,
            "MinTemperature": null,
            "Precipitation": null,
            "Snowfall": null,
            "SnowDepth": null
        },
        {
            "StationId": 50130,
            "StationName": "ALAMOSA WSO AP",
            "Timestamp": "\/Date(726130800000)\/",
            "MaxTemperature": null,
            "MinTemperature": null,
            "Precipitation": null,
            "Snowfall": null,
            "SnowDepth": null
        },
        {
            "StationId": 50130,
            "StationName": "ALAMOSA WSO AP",
            "Timestamp": "\/Date(726217200000)\/",
            "MaxTemperature": null,
            "MinTemperature": null,
            "Precipitation": null,
            "Snowfall": null,
            "SnowDepth": null
        },
        {
            "StationId": 50130,
            "StationName": "ALAMOSA WSO AP",
            "Timestamp": "\/Date(726303600000)\/",
            "MaxTemperature": null,
            "MinTemperature": null,
            "Precipitation": null,
            "Snowfall": null,
            "SnowDepth": null
        },
        {
            "StationId": 50130,
            "StationName": "ALAMOSA WSO AP",
            "Timestamp": "\/Date(726390000000)\/",
            "MaxTemperature": null,
            "MinTemperature": null,
            "Precipitation": null,
            "Snowfall": null,
            "SnowDepth": null
        },
        {
            "StationId": 50130,
            "StationName": "ALAMOSA WSO AP",
            "Timestamp": "\/Date(726476400000)\/",
            "MaxTemperature": null,
            "MinTemperature": null,
            "Precipitation": null,
            "Snowfall": null,
            "SnowDepth": null
        },
        {
            "StationId": 50130,
            "StationName": "ALAMOSA WSO AP",
            "Timestamp": "\/Date(726562800000)\/",
            "MaxTemperature": null,
            "MinTemperature": null,
            "Precipitation": null,
            "Snowfall": null,
            "SnowDepth": null
        },
        {
            "StationId": 50130,
            "StationName": "ALAMOSA WSO AP",
            "Timestamp": "\/Date(726649200000)\/",
            "MaxTemperature": null,
            "MinTemperature": null,
            "Precipitation": null,
            "Snowfall": null,
            "SnowDepth": null
        }
    ],
    "UserData": null
}

对于大多数列,空值将导致空单元格。但我希望至少能看到 StationIDs 和 StationNames。感谢您的观看。

【问题讨论】:

    标签: jquery wcf json jqgrid


    【解决方案1】:

    首先,如果服务器发回您发布的数据,jqGrid 将显示结果(参见http://www.ok-soft-gmbh.com/jqGrid/jsonfromsvc.htm)。当然,jqGrid 的效果不是很好,因为您使用StationId 作为 id,但 JSON 数据中的所有行都具有 相同 值 50130 作为 id。因此,例如,如果您选择一行,则会选择所有行。

    DateTime 不是标准的 JSON 类型,jqGrid 目前不支持它(参见this answerthis feature request)。要解决此问题,您必须在数据和 jqGrid 中至少创建一些 small changes

    当前的 JSON 数据中有很多为空值的数据。要减少从服务器发送的空数据的大小,请考虑使用EmitDefaultValue 属性。

    而且我觉得很奇怪,你不使用像这样的参数

    ajaxGridOptions: { contentType: "application/json" },
    serializeRowData: function (data) {return JSON.stringify(data);}
    

    (请参阅another old answer)。可能您的 WFC 目前没有收到任何输入参数,例如 int page, int rows, string sidx, string sord 等)。如果您至少发布您调用的服务器方法的原型。

    更新:我在创建小型 WCF 应用程序和调用 WCF 服务的 HTML 页面之前如何承诺。

    您当前的数据没有 IDStationId 字段不是键,因为它在不同的数据行中是相同的。如果您在数据中包含 id,您可以在列定义中包含选项 key:true 和 jqGrid 将使用数据作为 id。因为该示例仅用于显示数据而不进行数据编辑,所以我在从服务器发送的数据中包含了 no id。在 jqGrid 的情况下,使用以 1 开头的整数计数器作为行 ID。如果您决定在网格中包含编辑功能,则必须在数据中包含 id。

    现在我们进入代码。因为您写道您使用 Visual Studio 2010 并且没有回答任何关于 .NET 版本的问题,所以我在 .NET 4.0 中创建了一个应用程序。 web.config

    <?xml version="1.0"?>
    <configuration>
        <system.web>
            <compilation debug="true" targetFramework="4.0" />
        </system.web>
    
        <system.serviceModel>
            <standardEndpoints>
                <webHttpEndpoint>
                    <standardEndpoint helpEnabled="true"
                                      automaticFormatSelectionEnabled="true"/>
                </webHttpEndpoint>
            </standardEndpoints>
            <behaviors>
                <serviceBehaviors>
                    <behavior name="">
                        <serviceMetadata httpGetEnabled="true" />
                        <serviceDebug includeExceptionDetailInFaults="false" />
                    </behavior>
                </serviceBehaviors>
            </behaviors>
            <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
        </system.serviceModel>
    </configuration>
    

    文件WeatherDataService.svc

    <%@ ServiceHost Factory="System.ServiceModel.Activation.WebServiceHostFactory"
                    Service="WfcToJqGrid.WeatherDataService" %>
    

    文件IWeatherDataService.cs

    using System;
    using System.Collections.Generic;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.ServiceModel.Web;
    
    namespace WfcToJqGrid {
        [ServiceContract]
        public interface IWeatherDataService {
            [OperationContract,
             WebGet (RequestFormat = WebMessageFormat.Json,
                     ResponseFormat = WebMessageFormat.Json,
                     UriTemplate = "GetWeatherData?page={page}&rows={rows}" +
                                   "&sidx={sortIndex}&sord={sortDirection}")]
            WeatherDataForJqGrid GetDataForjqGrid (int page, int rows,
                                                   string sortIndex,
                                                   SortDirection sortDirection);
        }
    
        [DataContract]
        public enum SortDirection {
            [EnumMember (Value = "asc")]
            Asc,
            [EnumMember (Value = "desc")]
            Desc
        }
    
        // jsonReader: { repeatitems: false }
        [DataContract]
        public class WeatherDataForJqGrid {
            [DataMember (Order=0, Name = "total")]
            public int Total { get; set; }          // total number of pages
            [DataMember (Order = 1, Name = "page")]
            public int Page { get; set; }           // current zero based page number
            [DataMember (Order = 2, Name = "records")]
            public int Records { get; set; }        // total number of records
            [DataMember (Order = 3, Name = "rows")]
            public IEnumerable<WeatherData> Rows { get; set; }
        }
    
        [DataContract]
        public class WeatherData {
            [DataMember (Order=0)]
            public int StationId { get; set; }
            [DataMember (Order = 1)]
            public string StationName { get; set; }
            [DataMember (Order = 2)]
            public DateTime Timestamp { get; set; }
            [DataMember (Order = 3, EmitDefaultValue = false)]
            public string MaxTemperature { get; set; }
            [DataMember (Order = 4, EmitDefaultValue = false)]
            public string MinTemperature { get; set; }
            [DataMember (Order = 5, EmitDefaultValue = false)]
            public string Precipitation { get; set; }
            [DataMember (Order = 6, EmitDefaultValue = false)]
            public string Snowfall { get; set; }
            [DataMember (Order = 7, EmitDefaultValue = false)]
            public string SnowDepth { get; set; }
        }
    }
    

    文件WeatherDataService.svc.sc

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.ServiceModel.Web;
    using System.Net;
    
    namespace WfcToJqGrid {
        public class WeatherDataService : IWeatherDataService {
            // we use very simple database model to simulate a real data
            private static IQueryable<WeatherData> _repository = new List<WeatherData>{
                new WeatherData { StationId = 50130, StationName = "ALAMOSA WSO AP",
                                  Timestamp = new DateTime(1993,1,1,8,0,0)},
                new WeatherData { StationId = 50130, StationName = "ALAMOSA WSO AP",
                                  Timestamp = new DateTime(1993,1,2,8,0,0)},
                new WeatherData { StationId = 50130, StationName = "ALAMOSA WSO AP",
                                  Timestamp = new DateTime(1993,1,3,8,0,0)},
                new WeatherData { StationId = 50130, StationName = "ALAMOSA WSO AP",
                                  Timestamp = new DateTime(1993,1,4,8,0,0)},
                new WeatherData { StationId = 50130, StationName = "ALAMOSA WSO AP",
                                  Timestamp = new DateTime(1993,1,5,8,0,0)},
                new WeatherData { StationId = 50130, StationName = "ALAMOSA WSO AP",
                                  Timestamp = new DateTime(1993,1,6,8,0,0)},
                new WeatherData { StationId = 50130, StationName = "ALAMOSA WSO AP",
                                  Timestamp = new DateTime(1993,1,7,8,0,0)},
                new WeatherData { StationId = 50130, StationName = "ALAMOSA WSO AP",
                                  Timestamp = new DateTime(1993,1,8,8,0,0)},
                new WeatherData { StationId = 50130, StationName = "ALAMOSA WSO AP",
                                  Timestamp = new DateTime(1993,1,9,8,0,0)},
                new WeatherData { StationId = 50130, StationName = "ALAMOSA WSO AP",
                                 Timestamp = new DateTime(1993,1,10,8,0,0)}
            }.AsQueryable ();
    
            public WeatherDataForJqGrid GetDataForjqGrid (int page, int rows,
                                                          string sortIndex,
                                                          SortDirection sortDirection){
                int totalRecords = _repository.Count();
    
                // sorting of data
                IQueryable<WeatherData> orderdData = _repository;
                System.Reflection.PropertyInfo propertyInfo =
                    typeof(WeatherData).GetProperty (sortIndex);
                if (propertyInfo != null) {
                    orderdData = sortDirection == SortDirection.Desc ?
                        (from x in _repository
                         orderby propertyInfo.GetValue (x, null) descending
                         select x) :
                        (from x in _repository
                         orderby propertyInfo.GetValue (x, null)
                         select x);
                }
    
                // paging of the results
                IEnumerable<WeatherData> pagedData = orderdData
                    .Skip ((page > 0? page - 1: 0) * rows)
                    .Take (rows);
    
                // force revalidate data on the server on every request
                if (WebOperationContext.Current != null)
                    WebOperationContext.Current.OutgoingResponse.Headers.Set (
                        HttpResponseHeader.CacheControl, "max-age=0");
    
                return new WeatherDataForJqGrid {
                    Page = page,
                    Records = totalRecords,
                    Total = (totalRecords + rows - 1) / rows,
                    Rows = pagedData
                };
            }
        }
    }
    

    (阅读更多关于缓存的信息"jqGrid data stored in browser cache?") 和default.htm

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Demonstration how use jqGrid to call WFC service</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
        <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.5/themes/redmond/jquery-ui.css" />
        <link rel="stylesheet" type="text/css" href="http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-3.8/css/ui.jqgrid.css" />
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
        <script type="text/javascript" src="http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-3.8/js/i18n/grid.locale-en.js"></script>
        <script type="text/javascript" src="http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-3.8/js/jquery.jqGrid.min.js"></script>
        <script type="text/javascript" src="http://www.ok-soft-gmbh.com/jqGrid/json2.js"></script>
        <script type="text/javascript">
        //<![CDATA[
            jQuery(document).ready(function () {
                $("#list").jqGrid({
                    datatype: 'json',
                    url: 'WeatherDataService.svc/GetWeatherData',
                    jsonReader: { repeatitems: false },
                    loadui: "block",
                    mtype: 'GET',
                    rowNum: 5,
                    rowList: [5, 10, 20, 30],
                    viewrecords: true,
                    colNames: ['Station ID', 'Station Name', 'Timestamp', 'Max Temp',
                               'Min Temp', 'Precipitation', 'Snowfall', 'SnowDepth'],
                    colModel: [
                        { name: 'StationId', index: 'StationId', width: 100 },
                        { name: 'StationName', index: 'StationName', width: 150 },
                        { name: 'Timestamp', index: 'Timestamp', align: 'right', width: 250,
                            formatter: function (cellvalue, options, rowObject) {
                                // possible characters like "+0100" at the end of string will be ignored
                                return new Date(parseInt(cellvalue.substr(6, cellvalue.length - 8), 10));
                            }
                        },
                        { name: 'MaxTemperature', index: 'MaxTemperature', align: 'right', width: 100 },
                        { name: 'MinTemperature', index: 'MinTemperature', align: 'right', width: 100 },
                        { name: 'Precipitation', index: 'Precipitation', align: 'right', width: 100 },
                        { name: 'Snowfall', index: 'Snowfall', align: 'right', width: 100 },
                        { name: 'SnowDepth', index: 'SnowDepth', align: 'right', width: 100 },
                    ],
                    pager: '#pager',
                    sortname: 'Timestamp',
                    sortorder: 'asc',
                    height: "100%",
                    width: "100%",
                    prmNames: { nd: null, search: null }, // we switch of data caching on the server
                                                          // and not use _search parameter
                    caption: 'Weather Records'
                });
            });
        //]]>
        </script>
    </head>
    
    <body>
    
    <table id="list"><tr><td/></tr></table>
    <div id="pager"></div>
    
    </body>
    </html>
    

    您可以下载完整代码here

    【讨论】:

    • 感谢您的回复,奥列格。不幸的是,在实施您的建议后,我仍然无法加载网格。我将日期信息更改为 ISO 格式,并在 jqGrid 选项中添加了“格式化程序:'date'”。我还添加了 ajaxGridOptions 和 serializeRowData 属性。当我将 JSON 数据存储在文件中并将 url 属性更改为指向文件时,网格确实会加载。这让我想知道问题是否出在 ajax 调用和 Web 服务上。方法签名显示在下一条评论中。
    • [WebGet(ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)] [OperationContract] public string GetWeatherData(int page, int rows, string sidx, string sord) { // 获取数据 JavaScriptSerializer jsSerializer = new JavaScriptSerializer();字符串 jsonOutput = jsSerializer.Serialize(dataOutput);返回 json 输出; } }
    • 您使用哪个版本的 .NET?您使用 Visual Studio 2008 还是 2010?如果您回答问题,我可以为您发布相应的小代码示例。
    • 我们正在使用 VS 2010。感谢您的帮助。
    • 感谢 Oleg 抽出宝贵时间整理此示例。我已经下载了 ZIP 文件,将其解压缩并试用了该应用程序。它工作得很好。我从未打算使用 StationId 作为键值。 StationID 和 Timestamp 组合在一起形成一个独特的组合。我只是使用这个数据集作为探索 jqGrid 的一种方式。再次感谢您的帮助。
    猜你喜欢
    • 2011-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多