【问题标题】:Using jqGrid's inline-editing with RESTful urls?将 jqGrid 的内联编辑与 RESTful url 一起使用?
【发布时间】:2011-11-12 17:53:09
【问题描述】:

我正在使用 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 处理,或者我必须使用本地数据(如herehere 所述)并自己管理 ajax 调用?如果可能,我在网格上设置什么属性?

ajaxRowOptions 看起来很有希望,但documentation 的使用方法有点薄。)

【问题讨论】:

  • 您想使用哪种编辑模式:内联编辑、表单编辑、“动作”格式化程序或混合(如添加/删除表单编辑和内联编辑编辑)?
  • 理想情况下,用于创建新小部件的表单编辑、用于编辑它们的内联编辑以及用于删除它们的操作图标。 :) 第二个选择可能是所有三个的“选择一行然后单击按钮”模式。
  • 这一切都是可能的,只是代码不同而已。我会尝试在下次(可能明天)写下答案。今天我花太多时间在 jqGrid 上,不得不回到我的主要业务上。 :-)

标签: ajax rest jqgrid


【解决方案1】:

我已经通过实现 beforeSubmitCell 事件处理程序来实现它:

beforeSubmitCell: function(rowId) {

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

我使用的是 jqGrid 4.6 版本。

【讨论】:

    【解决方案2】:

    还可以查看这篇优秀的通用教程,了解如何为 RESTful URL 的 here 设置 jqGrid,其中还包括相应的 Spring MVC 服务器部分的外观。

    【讨论】:

      【解决方案3】:

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

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

      如果您使用导航工具栏的删除按钮,则在表单编辑中使用“删除”。查看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 将包含一些特殊字符(例如空格),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);
      }
      

      但我使用上面的代码能够使用方法editRowextraparam 内的函数(参见here 和问题描述here)。

      editRow中RESTfull URL(如/api/widgets/1)的用法很简单:

      $(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);
          }
      });
      

      需要注意的是,要从onclickSubmit 内部的postdata 中获取id,需要使用postdata.list_id 而不是postdata.id,其中'list' 是网格的ID。为了能够使用不同的网格 (<table>) id,可以使用 new 非标准参数。例如,在下面的代码中我使用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 格式选项。

      您的最后一个问题是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; }
      }
      

      您应该以某种方式包含哪些项目属性可以用作网格行的 id 的信息。页面上的 id 必须是 unique。如果您的数据没有 id,我建议您使用

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

      作为附加的jsonReader 方法,因为默认情况下,当前版本的 jqGrid 使用连续整数(“1”、“2”、“3”、...)作为行 ID。如果同一页面上至少有两个网格,则会出现问题。

      如果“GET”返回的数据大小超过 100 行,我建议您最好使用服务器端分页。这意味着您将在服务器部分添加一个 additional 方法,该方法支持服务器端数据的排序和分页。我建议您阅读the answer,其中我描述了为什么输入数据的标准格式不是 RESTfull 数组,并且还有pagetotalrecords。新方法对于经典的 RESTful 设计可能并不陌生,但是 native 甚至 SQL 代码中的排序和分页数据可以从最终用户方面显着提高整体性能。如果标准 jqGrid 输入参数的名称(pagerowssidxsord)可以使用 prmNames jqGrid 参数在那里重命名。

      【讨论】:

      • 感谢您的详尽回答!在文档中的哪里可以找到调用中的参数,例如: $("#grid").jqGrid('navGrid', '#pager', {edit: false, add: false, search: false}, { }, {}, { // 删除参数 url: '/api/widgets' });
      • 我认为这是对已构建网格的 API 调用,但我在 trirand.com/jqgridwiki/doku.php?id=wiki:methods 的方法列表中没有看到“navGrid”
      • @sprugman:我不确定我是否理解正确。 HerenavGrid 的文档中描述了prmEdit, prmAdd, prmDel, prmSearch, prmView 参数,它们是form editing 方法editGridRowdelGridRowsearchGriddelGridRow 的参数。 Here 被描述为 url 属性,例如 delGridRow
      • 或者我猜“导航器”部分更好。 trirand.com/jqgridwiki/doku.php?id=wiki:navigator
      • 是的,我找到了。我的意思是,对“navGrid”的调用有一堆参数{edit: false, etc.}, {}, {}。我试图找出那些空大括号的用途,等等。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-30
      相关资源
      最近更新 更多