2011-09-08 83 views
3

我正在使用jqGrid,并希望能够使用其内置的编辑功能,使Ajax调用添加/编辑/删除。我们的API使用REST风格的动词和URL像这样:使用jqGrid的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处理,或做我必须使用本地数据(如概述here & here)和管理阿贾克斯称自己?如果可能的话,我在网格上设置了哪些属性?

ajaxRowOptions看起来很有希望,但documentation是有点薄如何使用它。)

+0

要使用哪种编辑模式:内联编辑,表单编辑,“动作”格式化程序或某些组合(例如添加/删除表单编辑和内联编辑编辑)? – Oleg

+0

理想情况下,创建新窗口小部件的表单编辑,编辑它们的内联编辑以及删除它们的动作图标。 :)第二种选择可能是所有三种“选择一行然后单击一个按钮”模式。 – sprugman

+0

所有这一切都是可能的,但只有不同的代码。我会尽量在下次(可能明天)写下答案。今天,我花了太多时间用于jqGrid,不得不返回到我的主要业务。 :-) – Oleg

回答

10

POST在添加表格的使用默认情况下。

定制jqGrid for RESTfull后端的主要想法可以在the old answer中找到。

如果使用导航器工具栏的删除按钮,可以在表单编辑中使用“删除”。看看herehere。所以,你应该使用有关以下设置:

$("#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函数的例子中使用,以确保如果ID都会有一些特殊的字符(空格例如)如果将进行编码,使得服务器部分自动接收到原始(解码)的数据。可能您需要为在发送删除请求到服务器期间使用的$.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是不可能的,因为需要使用不同的基址('/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' 
    }); 

和 明确设置为内联用“把”编辑您可以设置以下默认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"不是一般的要求,但它可能需要一些SE技术。上例中的回调函数serializeRowData以JSON形式发送数据。它不是RESTfull所必需的,但它很常见。功能JSON.stringify本地在最新的Web浏览器中实现,但要确保它在旧版浏览器中可以正常工作,则应在您的页面上包含json2.js

serializeRowData代码也能像

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

很简单,但我用上面的代码,以便能够使用的功能的方法editRowextraparam的内部(参见here和问题说明here)。

的REST类型的URL(如/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); 
    } 
}); 

重要的是要得到idpostdata里面的onclickSubmit和需要使用postdata.list_id而不是postdata.id,其中'list'是网格的id。为了能够使用不同的网格(<table>)ID可以使用新的非标准参数。例如,在下面的代码我使用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'使用的情况下(见herehere)配有内联或形式编辑(或混合),您可以使用前面所述的相同技术,但使用editOptionsdelOptions formatoptions转发所有需要的编辑/删除选项。

最后一个问题是使用GET作为/api/widgets。传统的RESTfull服务将返回所有项目的数组作为/api/widgets上的响应。因此,您应该只使用loadonce: truejsonReader,它们使用方法而不是属性(请参阅herehere)。

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

您应该以某种方式包含哪些item属性可以用作网格行的id。该页面上的ID必须为unique。它的数据没有ID我会建议你使用

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

作为附加jsonReader方法,因为每默认jqGrid的当前版本的使用顺序整数(“1”,“2”,“3”,.. )作为行ID。如果在同一个页面上至少有两个网格,它将跟随这些问题。

如果'GET'返回的数据大小多于100行,我建议您最好使用服务器端分页。这意味着您将在支持服务器端排序和数据分页的服务器部分添加一个附加的方法。我建议您阅读the answer,我在这里描述了为什么输入数据的标准格式不是RESTfull数组项目,并且还有page,totalrecords。对于传统的RESTful设计,新方法可能并不陌生,但本地或甚至SQL代码中的排序和分页数据可以显着提高最终用户的总体性能。如果标准jqGrid输入参数的名称(pagerows,sidxsord)可以使用prmNames jqGrid参数在那里重命名。

+0

感谢您的彻底解答!在文档中,我可以找到这样的参数:$(“#grid”)。jqGrid('navGrid','#pager', {edit:false,add:false,search:false}, {},{}, {//删除参数 url:'/ api/widgets' }); – sprugman

+0

我认为这是一个已经建好的网格上的API调用,但是在http://www.trirand.com/jqgridwiki/doku.php?id=wiki:methods方法列表中看不到'navGrid' – sprugman

+0

哦,找到它了。当然在“自定义按钮”下。 : - | – sprugman

1

还检查了关于如何建立jqGrid的REST风格的URL的here,其中还包括相应的Spring MVC的服务器部分会怎样看这个优秀的通用教程。

0

我设法通过实施beforeSubmitCell事件处理程序来实现它:

beforeSubmitCell: function(rowId) { 

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

我使用的jqGrid 4.6版本。