【问题标题】:jqgrid Page 1 of x pagerjqgrid x pager 的第 1 页
【发布时间】:2011-03-10 19:57:28
【问题描述】:

我试图弄清楚如何使用 jqGrid 的分页功能。 目前我被困在第 1 页,共 4 页。无论我是否按下下一步按钮。它只停留在 1。

我正在使用带有 Web 服务的 ASP.Net 来填充我的 JSON 数据。如何从客户端捕获事件以填充 Web 服务上的属性以恢复正确的值?

感谢任何帮助。

【问题讨论】:

    标签: asp.net jqgrid web-services jqgrid-asp.net


    【解决方案1】:

    如果按下“下一步”按钮,则会向服务器发送一个新请求。该请求将包含page=2 和例如rows=10 参数作为URL 的一部分(如果想要获取第二页的下10 行)。

    您的服务器代码应读取此参数并发送回相应的数据行。从服务器发回的 JSON 数据应如下所示

    { 
      "total": "5", 
      "page": "2", 
      "records": "55",
      "rows" : [
        {"id" :"21", "cell" :["cell11", "cell12", "cell13"]},
        {"id" :"22", "cell" :["cell21", "cell22", "cell23"]},
          ...
        {"id" :"30", "cell" :["cell31", "cell32", "cell33"]},
      ]
    }
    

    (请参阅http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#json_data)。所以数据必须包含page (page=2) 的正确值。一般来说,现在您有可能像以前一样拥有更少的数据,并且您在请求中返回第 1 页以获取第 2 页。

    所以我建议目前您的服务器代码不要在输出中返回正确的 page 值。

    更新:好的,杰夫。我在jqgrid setGridParam datatype:local 中继续我的回答并发布如何承诺代码如何进行服务器端分页、排序和搜索(或高级搜索)。

    首先在示例中,我不会真正实现排序和搜索,而只会在您现在遇到问题的地方模拟分页。真正的分页、排序和查找应该是通过对应的SELECT语句到数据所在的SQL数据库来实现的。排序遵循ORDER BY,搜索到WHERE,并分页到TOP(x)TOP(x)LEFT OUTER JOINROW_NUMBER() OVER(...) 构造的使用。但这些都不是你问题的主题。所以我把一切都简化为数据分页的简单模拟。

    我从 ASMX Web Method 的代码开始:

    public JqGridData TestMethod (int page, int rows, string sidx, string sord,
        bool _search, string searchField, string searchOper, string searchString) {
        // for advance search use "string filters" instead of the last three parameters
        int recordsCount = 205;
    
        int startIndex = (page - 1) * rows;
        int endIndex = (startIndex + rows < recordsCount) ?
                       startIndex + rows : recordsCount; 
        List<TableRow> gridRows = new List<TableRow> (rows);
        for (int i = startIndex; i < endIndex; i++) {
            gridRows.Add (new TableRow () {
                id = i,
                cell = new List<string> (2) {
                    string.Format("Name{0}", i), 
                    string.Format("Title{0}", i)
                }
            });
        }
    
        return new JqGridData () {
            total = (recordsCount + rows - 1) / rows,
            page = page,
            records = recordsCount,
            rows = gridRows
        };
    }
    

    JqGridDataTableRow 类的定义如下:

    public class TableRow {
        public int id { get; set; }
        public List<string> cell { get; set; }
    }
    public class JqGridData {
        public int total { get; set; }
        public int page { get; set; }
        public int records { get; set; }
        public List<TableRow> rows { get; set; }
    }
    

    我们跳过对TestMethod 的输入参数的任何验证,以使代码示例更具可读性。

    现在是客户端代码:

    $("#list").jqGrid({
        url: './MyTestWS.asmx/TestMethod',
        datatype: 'json',
        mtype: 'POST',
        ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
        serializeGridData: function (postData) {
            if (postData.searchField === undefined) postData.searchField = null;
            if (postData.searchString === undefined) postData.searchString = null;
            if (postData.searchOper === undefined) postData.searchOper = null;
            //if (postData.filters === undefined) postData.filters = null;
            return JSON.stringify(postData);
        },
        jsonReader: {
            root: function (obj) { return obj.d.rows; },
            page: function (obj) { return obj.d.page; },
            total: function (obj) { return obj.d.total; },
            records: function (obj) { return obj.d.records; }
        },
        // you can also use following more simple form of jsonReader instead:
        // jsonReader: { root: "d.rows", page: "d.page", total: "d.total",
        //               records: "d.records", id: "d.names" }
        colModel: [
            { name: 'name', label: 'Name', width: 250 },
            { name: 'title', label: 'Title', width: 250 }
        ],
        rowNum: 10,
        rowList: [10, 20, 300],
        sortname: 'name',
        sortorder: "asc",
        pager: "#pager",
        viewrecords: true,
        gridview: true,
        rownumbers: true,
        height: 250,
        caption: 'My first grid'
    }).jqGrid('navGrid', '#pager', {edit: false, add: false, del: false, search: true});
    //                {}, // use default settings for edit
    //                {}, // use default settings for add
    //                {}, // delete instead that del:false we need this
    //                {multipleSearch : true} // enable the advanced searching
    //                );
    

    在代码中,我使用了与jqgrid setGridParam datatype:local 相同的技术,但serializeGridData 函数的代码有点不同。因为我们使用 POST 而不是 GET 方法从服务器获取数据必须始终设置 web 方法的所有输入参数。另一方面,jqGrid 并不总是设置参数searchFieldsearchOpersearchString,但前提是_search=true。例如,在第一次加载 jqGrid 时,_search=falsesearchFieldsearchOpersearchString 未在 postData 中定义。为了解决这个问题,我们使用null 初始化未定义的参数。

    要实现排序,需要使用sidx(排序索引)和sord(排序方向:"asc""desc")参数。

    要实现搜索,需要使用其他参数_searchsearchFieldsearchOpersearchString

    在高级搜索期间,必须使用参数 filters 而不是 searchFieldsearchOpersearchString 参数(参见注释行)。必须根据 JSON 反序列化器对数据进行解码。所以必须在jqgrid中设置multipleSearch : trueserializeGridData 函数应替换为

    serializeGridData: function (postData) {
        if (postData.filters === undefined) postData.filters = null;
        return JSON.stringify(postData);
    }
    

    并且web方法的原型应该改成

    public JqGridData TestMethod (int page, int rows, string sidx, string sord,
        bool _search, string filters)
    

    解码参数filters可以使用这样简单的代码:

    if (_search && !String.IsNullOrEmpty (filters)) {
        JavaScriptSerializer serializer = new JavaScriptSerializer ();
        jqGridSearchFilter searchFilter =
            serializer.Deserialize<jqGridSearchFilter> (filters);
        // use the searchFilter here
    }
    

    jqGridSearchFilter 类的定义如下:

    public class jqGridSearchFilterItem {
        public string field { get; set; }
        public string op { get; set; }
        public string data { get; set; }
    }
    public class jqGridSearchFilter {
        public string groupOp { get; set; }
        public List<jqGridSearchFilterItem> rules { get; set; }
    }
    

    我希望这些信息足以让您在 ASMX Web 方法方面实现任何类型的 jqGrid 用法。

    我在这里使用了从服务器发送到客户端的最简单的数据,并在主数据之外添加了额外的id。如果您在表中的一列是id,您可以稍微减少发送到服务器的数据。详情请见Jqgrid 3.7 does not show rows in internet explorer

    【讨论】:

    • 感谢您的回复,但是,我将页面值完全取出,它仍然无法正常工作。目前,我的网络服务每次调用时都会从数据库中获取整个记录集。如何捕获对“下一个”或“上一个”按钮的单击,以便将某些内容传递到我的 Web 服务中?有什么想法吗?
    • 当我点击“下一步”按钮时,有没有办法捕捉传递回网络服务的内容?
    • 为了捕获我主要使用 Fiddler 的 HTTP 流量(参见 fiddler2.com)。使用非常简单。如果服务器在本地运行,您可能会遇到的唯一问题。在这种情况下,您应该将 URL localhost 替换为伪名称 ipv4.fiddler。
    • 对于数据分页,通常由负责的服务器进行。在新的 3.7.x 版本的 jqGrid 中,可以使用本地分页。试试 jqGrid 的loadonce:true 参数。您还可以使用onPaging 事件(请参阅trirand.com/jqgridwiki/doku.php?id=wiki:events#list_of_events),该事件在单击新页面按钮后触发。
    • @Oleg:谢谢它终于可以工作了。我做的一个小改动是对 JSON 阅读器。我不确定为什么您的示例对我不起作用(可能是我的对象从 WS 返回)。我将其更改为:jsonReader:{ root:“d.rows”,page:“d.page”,total:“d.total”,records:“d.records”,repeatitems:false,id:“d.names " },然后它就开始工作了!你的例子会帮助很多人。谢谢你陪我走到最后。
    【解决方案2】:

    好的,我正在回答这个问题,因为我接受了 Oleg 上面所说的内容,但明白了他的意思。

    我的 .ajax 调用包含在一个将 postdata 作为参数传递的函数中。我找不到有关该参数的任何文档,但我认为这可能是包含页面值的地方。如您所见,我使用 postdata.page 和 low 发出警报,结果我得到了一个值(基于单击下一个按钮)。

    所以我在我的 web 服务中创建了一个名为 page (integer) 的参数。

    顺便说一句,您将一个整数值从 jQuery 传递到您的 ASP.Net 网络服务,如下所示:

    data: "{'page':'" + postdata.page + "'}"
    

    下面是完整的功能:

    function processrequest(postdata) {
    alert(postdata.page);
    $(".loading").show();
    $.ajax({
        type: "POST",
        data: "{'page':'" + postdata.page + "'}",
        datatype: "json",
        url: "../webServices/myTestWS.asmx/testMethod",
        contentType: "application/json; charset-utf-8",
        complete: function (jsondata, stat) {
            if (stat == "success") {
                var thegrid = jQuery("#list")[0];
                var jsonObject = (eval("(" + jsondata.responseText + ")"));
                thegrid.addJSONData(jsonObject.d);
                $(".loading").hide();
            } else {
                $(".loading").hide();
                alert("Error with AJAX callback");
            }
        }
    });
    

    }

    【讨论】:

    • stackoverflow.com/questions/3151565/… 我试着解释你不要使用$.ajax 而是使用ajaxGridOptions: { contentType: 'application/json; charset=utf-8' }。如果您发布 testMethod 的代码(它可以在一个返回语句中直接返回一些测试数据),我将对其进行更改以展示如何在不使用 addJSONData 的情况下轻松使用 jqGrid。
    • Oleg,如果您不使用 .ajax 调用您的 Web 服务,您将如何使用 ajaxGridOptions 进行设置?我找不到可以明确说明这一点的示例。
    • 公共函数 testMethod() As myTest Dim myString As New myTest myString.records = 2 myString.total = 2 myString.page = 1 Dim myName As New names Dim myName2 As New names Dim myNamesList As New List (姓名) myName.name = "Jeff" myName.title = "Programmer" myName2.name = "Steve" myName2.title = "Programmer" myNamesList.Add(myName) myNamesList.Add(myName2) myString.rows = myNamesList Return myString 结束函数
    • @Oleg:我终于找到了一些如何使用 ajaxGridOptions 来调用我的 web 服务的示例。但是我现在有一个错误:“消息”:“无效的 JSON 原语:_search。url:'../webServices/myTestWS.asmx/testMethod',数据类型:'json',ajaxGridOptions:{ contentType:'application/json;charset =utf-8' }, mtype: 'POST', 现在怎么办?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-26
    相关资源
    最近更新 更多