使用jqGrid的内联编辑与RESTful网址?

spr*_*man 3 ajax rest jqgrid

我正在使用jqGrid,并希望能够使用其内置的编辑功能来进行添加/编辑/删除的ajax调用.我们的API使用RESTful动词和网址,如下所示:

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
Run Code Online (Sandbox Code Playgroud)

是否可以使用带有这些限制的内置ajax处理,或者我是否必须使用本地数据(如此此处所述)并自行管理ajax调用?如果可能,我在网格上设置了哪些属性?

(ajaxRowOptions看起来很有希望,但文档在如何使用它方面有点薄.)

Ole*_*leg 10

POST默认情况下,在"添加"表单中使用.

您可以在旧答案中找到为RESTfull后端自定义jqGrid的主要想法.

如果使用导航器工具栏的"删除"按钮,则在表单编辑中使用"DELETE".看这里这里.所以你应该使用以下设置:

$("#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);
        }
    });
Run Code Online (Sandbox Code Playgroud)

我在上面的例子中使用encodeURIComponent函数来确保如果id将有一些特殊字符(例如空格),如果将被编码,以便服务器部分自动接收原始(解码)数据.可能需要为$.ajax将Delete请求发送到服务器时使用的调用设置一些其他设置.您可以使用它的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);
    }
});
Run Code Online (Sandbox Code Playgroud)

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);
    }
});
Run Code Online (Sandbox Code Playgroud)

然后用的navGrid应该是明确的设置url

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

要在内联编辑中使用"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);
    }
});
Run Code Online (Sandbox Code Playgroud)

contentType: "application/json"一般情况下不需要该设置,但某些服务器技术可能需要该设置.上例中的回调函数serializeRowData将数据作为JSON发送.RESTfull不需要它,但它很常见.该函数JSON.stringify在最新的Web浏览器中本机实现,但为了确保它在旧浏览器中工作,您应该在页面上包含json2.js.

代码serializeRowData可以非常简单

serializeRowData: function (data) {
    return JSON.stringify(data);
}
Run Code Online (Sandbox Code Playgroud)

但我用上面的代码,以便能够使用的内部功能extraparam的方法的editRow(见这里和问题说明这里).

RESTfull URL(如/api/widgets/1)的使用editRow非常简单:

$(this).editRow(rowid, true, null, null, '/api/widgets/' + encodeURIComponent(rowid));
Run Code Online (Sandbox Code Playgroud)

要在表单编辑的情况下使用它,您应该使用它

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

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

重要的是要注意idpostdata内部获取onclickSubmit并需要使用postdata.list_id而不是postdata.id,'list'网格的id 在哪里.为了能够使用不同的grid(<table>)id,可以使用的非标准参数.例如,在下面的代码中我使用myGridId:

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

和默认设置定义为

$.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']);
    }
});
Run Code Online (Sandbox Code Playgroud)

在使用的情况下格式化:"动作"(见这里这里)与在线或表单编辑(或混合),可以使用如前文所述相同的技术,但将所有需要编辑/删除使用选项editOptionsdelOptionsformatoptions.

最后一个问题是GETas 的用法/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; }
}
Run Code Online (Sandbox Code Playgroud)

您应该以某种方式包含哪些项属性可以用作网格行的ID的信息.id必须unique在页面上.你的数据没有id我建议你使用

id: function () { return $.jgrid.randId(); }
Run Code Online (Sandbox Code Playgroud)

作为一种额外的jsonReader方法,因为默认情况下,当前版本的jqGrid使用顺序整数("1","2","3",...)作为行ID.如果在同一页面上至少有两个网格,则会出现问题.

如果'GET'返回的数据大小超过100行,我建议您更好地使用服务器端分页.这意味着您将在服务器部分添加一个支持服务器端排序和数据分页的附加方法.我建议你阅读答案,其中我描述了为什么输入数据的标准格式不是RESTfull项目数组page,total并且records还有.对于经典的RESTful设计,新方法可能并不奇怪,但是本甚至SQL代码中的排序和分页数据可以极大地提高最终用户的总体性能.如果标准jqGrid的输入参数的名称(page,rows,sidxsord),可以使用prmNames的jqGrid参数来重命名那里.