Использование встроенного редактирования jqGrid с RESTful URL-адресами? - PullRequest
3 голосов
/ 08 сентября 2011

Я использую jqGrid и хотел бы иметь возможность использовать его встроенные функции редактирования для выполнения вызовов ajax для добавления / редактирования / удаления. Наш API использует RESTful глаголы и URL, например:

verb     url               action
--------------------------------------------------------------
GET      /api/widgets      get all widgets (to populate grid)
POST     /api/widgets      create new widget
PUT      /api/widgets/1    update widget 1
DELETE   /api/widgets/1    delete widget 1

Можно ли использовать встроенную обработку ajax с этими ограничениями, или мне нужно использовать локальные данные (как указано здесь & здесь ) и управлять вызовами ajax себя? Если это возможно, какие свойства я должен установить в сетке?

(ajaxRowOptions выглядит многообещающе, но документация немного тонка в том, как его использовать.)

Ответы [ 3 ]

10 голосов
/ 09 сентября 2011

Использование POST в форме добавления по умолчанию.

Основная идея настройки jqGrid для бэкэнда RESTfull находится в старом ответе .

* 1007.* Использовать «УДАЛИТЬ» при редактировании формы, если вы используете кнопку «Удалить» на панели инструментов навигатора.Посмотрите на здесь или здесь .Поэтому вы должны использовать примерно следующие настройки:
$("#grid").jqGrid('navGrid', '#pager',
    {edit: false, add: false, search: false}, {}, {},
    { // Delete parameters
        mtype: "DELETE",
        serializeDelData: function () {
            return ""; // don't send and body for the HTTP DELETE
        },
        onclickSubmit: function (params, postdata) {
            params.url = '/api/widgets/' + encodeURIComponent(postdata);
        }
    });

Я использую в приведенном выше примере функцию encodeURIComponent , чтобы быть уверенным, что если идентификатор будет иметь некоторые специальные символы (например, пробелы)if будет закодирован так, чтобы серверная часть автоматически получала исходные (декодированные) данные.Возможно, вам потребуется установить некоторые дополнительные настройки для вызова $.ajax, используемого при отправке запроса на удаление на сервер.Вы можете использовать для него ajaxDelOptions свойство.

Вы можете сделать вышеуказанные настройки как ваши настройки по умолчанию .Вы можете сделать это в отношении следующего

$.extend($.jgrid.del, {
    mtype: "DELETE",
    serializeDelData: function () {
        return ""; // don't send and body for the HTTP DELETE
    },
    onclickSubmit: function (params, postdata) {
        params.url = '/api/widgets/' + encodeURIComponent(postdata);
    }
});

Метод onclickSubmit из приведенного выше примера можно использовать для операций редактирования (в случае редактирования формы) для динамического изменения URL-адреса до /api/widgets/1,Во многих случаях использование onclickSubmit в приведенной выше форме невозможно, поскольку необходимо использовать разные базовые URL ('/api/widgets') для разных сеток.В случае, если можно использовать

$.extend($.jgrid.del, {
    mtype: "DELETE",
    serializeDelData: function () {
        return ""; // don't send and body for the HTTP DELETE
    },
    onclickSubmit: function (params, postdata) {
        params.url += '/' + encodeURIComponent(postdata);
    }
});

, тогда использование navGrid должно быть с явной настройкой url

$("#grid").jqGrid('navGrid', '#pager',
    {edit: false, add: false, search: false}, {}, {},
    { // Delete parameters
        url: '/api/widgets'
    });

и использовать 'PUT' во встроенном редактировании.Можно установить следующие настройки jqGrid по умолчанию:

$.extend($.jgrid.defaults, {
    ajaxRowOptions: { contentType: "application/json", type: "PUT", async: true },
    serializeRowData: function (data) {
        var propertyName, propertyValue, dataToSend = {};
        for (propertyName in data) {
            if (data.hasOwnProperty(propertyName)) {
                propertyValue = data[propertyName];
                if ($.isFunction(propertyValue)) {
                    dataToSend[propertyName] = propertyValue();
                } else {
                    dataToSend[propertyName] = propertyValue;
                }
            }
        }
        return JSON.stringify(dataToSend);
    }
});

Настройка contentType: "application/json" в общем случае не требуется, но может потребоваться для некоторых серверных технологий.Функция обратного вызова serializeRowData из вышеприведенного примера отправляет данные в формате JSON.Это не требуется для RESTfull, но это очень распространено.Функция JSON.stringify изначально реализована в самых последних веб-браузерах, но чтобы быть уверенным, что она работает в старых браузерах, вам следует включить json2.js на вашу страницу.

КодserializeRowData может быть очень простым, например

serializeRowData: function (data) {
    return JSON.stringify(data);
}

, но я использую приведенный выше код, чтобы иметь возможность использовать функции внутри extraparam метода editRow (см. здесь и описание проблемы здесь ).

Использование URL-адреса RESTfull (например, /api/widgets/1) в editRow очень просто:

$(this).editRow(rowid, true, null, null, '/api/widgets/' + encodeURIComponent(rowid));

Чтобы использовать его в случае редактирования формы, вы должны использовать

grid.navGrid('#pager', {},
    { mtype: "PUT", url: '/api/widgets' });

и

$.extend($.jgrid.edit, {
    ajaxEditOptions: { contentType: "application/json" }, // can be not required
    onclickSubmit: function (params, postdata) {
        params.url += '/' + encodeURIComponent(postdata.list_id);
    }
});

Важно отметить, что для получения id из postdataвнутри onclickSubmit и нужно использовать postdata.list_id вместо postdata.id, где 'list' - идентификатор сетки.Чтобы иметь возможность использовать разные идентификаторы сетки (<table>), можно использовать новый нестандартный параметр.Например, в приведенном ниже коде я использую myGridId:

var myEditUrlBase = '/api/widgets';
grid.navGrid('#pager', {},
    { mtype: "PUT", url: myEditUrlBase, myGridId: 'list' },
    { // Add options
        url: myEditUrlBase },
    { // Delete options
        url: myEditUrlBase });

и настройку по умолчанию, определенную как

$.extend($.jgrid.del, {
    mtype: "DELETE",
    serializeDelData: function () {
        return ""; // don't send and body for the HTTP DELETE
    },
    onclickSubmit: function (params, postdata) {
        params.url += '/' + encodeURIComponent(postdata);
    }
});

$.extend($.jgrid.edit, {
    ajaxEditOptions: { contentType: "application/json" }, // can be not required
    onclickSubmit: function (params, postdata) {
        params.url += '/' + encodeURIComponent(postdata[params.myGridId + '_id']);
    }
});

В случае использования formatter: 'actions' (см. здесь и здесь ) со встроенным редактированием или редактированием формы (или микшированием), вы можете использовать ту же технику, что описана выше, но перенаправить все необходимые опции редактирования / удаленияиспользуя editOptions и delOptions formatoptions.

Последним вашим вопросом было использование GET как /api/widgets.Классические сервисы RESTfull возвращают только массив всех элементов в качестве ответа на /api/widgets.Таким образом, вы должны просто использовать loadonce: true и jsonReader, которые использовали методы вместо свойств (см. здесь и здесь ).

loadonce: true,
jsonReader: {
    repeatitems: false,
    root: function (obj) { return obj; },
    page: function () { return 1; },
    total: function () { return 1; },
    records: function (obj) { return obj.length; }
}

Вы должны в некоторыхСпособ включает информацию о том, какое свойство элемента можно использовать в качестве идентификатора строк сетки.Идентификатор должен быть unique на странице.Если ваши данные не имеют идентификатора, я бы порекомендовал вам использовать

id: function () { return $.jgrid.randId(); }

в качестве дополнительного метода jsonReader, потому что по умолчанию текущая версия jqGrid использует последовательные целые числа ("1", "2", "3", ...) в качестве идентификаторов строк.В случае наличия как минимум двух сеток на одной странице это приведет к проблемам.

Если размер данных, возвращаемых GET, превышает 100 строк, я бы рекомендовал вам использовать подкачку на стороне сервера. Это означает, что вы добавите дополнительный метод в серверную часть, который поддерживает сортировку и подкачку данных на стороне сервера. Я рекомендую прочитать ответ , где я описал , почему стандартный формат входных данных не является массивом элементов RESTfull и имеет дополнительно page, total и records , Новый метод, вероятно, не будет странным для классического дизайна RESTful, но сортировка и разбиение на страницы данных в native или даже в коде SQL могут значительно повысить общую производительность со стороны конечного пользователя. Если имена стандартных входных параметров jqGrid (page, rows, sidx и sord), вы можете использовать параметр prmNames jqGrid для переименования там.

1 голос
/ 29 июня 2012

Также ознакомьтесь с этим прекрасным общим руководством, чтобы узнать, как настроить jqGrid для URL-адресов RESTful здесь , что также включает в себя то, как будет выглядеть соответствующая серверная часть Spring MVC.

0 голосов
/ 09 июля 2014

Мне удалось добиться этого путем реализации обработчика события beforeSubmitCell:

beforeSubmitCell: function(rowId) {

            jQuery("#grid-HumanResource-table").jqGrid(
                'setGridParam',
                {
                    cellurl: s.getBaseModule().config.baseAPIUrl + "humanResource/" + rowId
                }
            );
        },

Я использую версию jqGrid 4.6.

...