jqgrid Страница 1 из x пейджер

Я пытаюсь понять, как использовать функцию разбиения на страницы jqGrid. В настоящее время я застрял на странице 1 из 4. Неважно, нажимаю я кнопку «Далее» или нет. Он просто остается на 1.

Я использую ASP.Net с веб-сервисом для заполнения моих данных JSON. Как захватить событие от клиента, чтобы заполнить свойство в веб-сервисе, чтобы вернуть правильное значение?

Любая помощь приветствуется.


person webdad3    schedule 01.07.2010    source источник


Ответы (2)


Если нажать кнопку «Далее», на сервер будет отправлен новый запрос. Запрос будет содержать параметры 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 JOIN или с использованием конструкций ROW_NUMBER() OVER(...). Но все это не предмет вашего вопроса. Поэтому я сводил все к простой симуляции разбиения на страницы данных.

Я начинаю с кода веб-метода ASMX:

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
    };
}

где классы JqGridData и TableRow определены следующим образом:

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 для получения данных с сервера, все входные параметры веб-метода должны быть всегда установлены. С другой стороны jqGrid устанавливает не всегда параметры searchField, searchOper и searchString, а только если _search=true. Например, при первой загрузке jqGrid _search=false и searchField, searchOper и searchString не определены в postData. Чтобы решить эту проблему, мы инициализируем неопределенные параметры с помощью null.

Для реализации сортировки необходимо использовать параметры sidx (индекс сортировки) и sord (направление сортировки: "asc" или "desc").

Для осуществления поиска необходимо использовать другие параметры _search, searchField, searchOper, searchString.

При расширенном поиске вместо параметров searchField, searchOper, searchString необходимо использовать параметр filters (см. Закомментированные строки). Данные должны быть декодированы с использованием десериализатора JSON. Значит, должно быть установлено multipleSearch : true в jqgrid. Функцию serializeGridData следует заменить на

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

и прототип веб-метода должен быть изменен на

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; }
}

Я надеюсь, что этой информации вам будет достаточно для реализации любого вида использования jqGrid в отношении веб-метода ASMX.

Я использовал здесь простейшую отправку данных с сервера клиенту с дополнительными id помимо основных данных. Если один из столбцов в таблице - это id, вы можете немного уменьшить количество данных, отправляемых на сервер. См. Jqgrid 3.7 не показывает строки в internet explorer, чтобы получить более подробную информацию.

person Oleg    schedule 01.07.2010
comment
Спасибо за ответ, однако я полностью удалил значение страницы, и оно по-прежнему не работает. В настоящее время мой веб-сервис захватывает весь набор записей из БД каждый раз, когда он вызывается. Как я могу зафиксировать нажатие следующей или предыдущей кнопки, чтобы передать что-то в свой веб-сервис? Любые идеи? - person webdad3; 02.07.2010
comment
Есть ли способ зафиксировать, что передается обратно в веб-сервис, когда я нажимаю следующую кнопку? - person webdad3; 02.07.2010
comment
Для захвата HTTP-трафика я в основном использую Fiddler (см. fiddler2.com). Использование очень простое. Единственная проблема, которая может возникнуть, если сервер работает локально. В случае, если вы должны заменить в URL localhost на псевдо-имя ipv4.fiddler. - person Oleg; 02.07.2010
comment
За подкачку данных обычно отвечает сервер. В новой версии jqGrid 3.7.x возможно использование локального разбиения по страницам. Попробуйте loadonce:true параметр jqGrid. Вы также можете использовать событие onPaging (см. trirand.com/jqgridwiki/ doku.php? id = wiki: events # list_of_events), который срабатывает после нажатия кнопки новой страницы. - person Oleg; 02.07.2010
comment
@Oleg: Спасибо, наконец-то заработало. Одно небольшое изменение, которое я сделал, касается программы чтения JSON. Я не совсем уверен, почему ваш пример не сработал для меня (возможно, мой объект был возвращен из WS). Я изменил его на: jsonReader: {root: d.rows, page: d.page, total: d.total, records: d.records, repeatitems: false, id: d.names}, и затем он начал работать! Ваш пример поможет многим людям. Спасибо, что провели меня до конца. - person webdad3; 04.07.2010
comment
@Джефф. Пожалуйста! На trirand.com/blog/?page_id=393/help/ Я обещал вам помочь с рабочим примером, поэтому ваша проблема должна в конце концов решиться. Насчет jsonReader: оба пути должны работать. Так что использование точечной нотации JSON абсолютно нормально. Я только хотел дать больше вариаций jsonReader по сравнению с тем, что я писал раньше. - person Oleg; 04.07.2010

Хорошо, я отвечаю на этот вопрос, поскольку я взял то, что Олег сказал выше, но точно понял, что он имел в виду.

Мой вызов .ajax заключен в функцию, которая передает постданные в качестве параметра. Мне не удалось найти никакой документации по этому параметру, но я подумал, что, возможно, именно здесь содержится значение страницы. Как видите, я сделал предупреждение с postdata.page и low, и вот, я получил значение (основанное на нажатии следующей кнопки).

Итак, я создал параметр в моем веб-сервисе под названием 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");
        }
    }
});

}

person webdad3    schedule 01.07.2010
comment
В stackoverflow.com/questions/3151565/ Я попытался объяснить, что вы не используете $.ajax и вместо этого используете ajaxGridOptions: { contentType: 'application/json; charset=utf-8' }. Если вы разместите код своего testMethod (он может возвращать некоторые тестовые данные непосредственно в одном операторе возврата), я изменю его, чтобы показать, как вы можете легко использовать jqGrid без использования addJSONData. - person Oleg; 02.07.2010
comment
Олег, если вы не используете .ajax для вызова своего веб-сервиса, как бы вы настроили его с помощью ajaxGridOptions? Мне не удалось найти примеров, которые бы четко это подтверждали. - person webdad3; 02.07.2010
comment
Открытая функция testMethod () As myTest Dim myString As New myTest myString.records = 2 myString.total = 2 myString.page = 1 Уменьшить myName как новые имена Dim myName2 как новые имена Dim myNamesList как новый список (имен) myName.name = Джефф myName.title = Программист myName2.name = Стив myName2.title = Программист myNamesList.Add (myName) myNamesList.Add (myName2) myString.rows = myNamesList Вернуть конечную функцию myString - person webdad3; 03.07.2010
comment
@Oleg: Наконец-то я нашел несколько примеров того, как использовать ajaxGridOptions для вызова моего веб-сервиса. Однако теперь у меня есть ошибка: Сообщение: недопустимый примитив JSON: _search. url: '../webServices/myTestWS.asmx/testMethod', тип данных: 'json', ajaxGridOptions: {contentType: 'application / json; charset = utf-8 '}, mtype:' POST ', что теперь? - person webdad3; 03.07.2010