【问题标题】:Wait for backend service response before making changes to ag-grid table在更改 ag-grid 表之前等待后端服务响应
【发布时间】:2020-03-04 03:14:17
【问题描述】:

我正在使用 ag-grid/ag-grid-angular 来提供由数据库支持的可编辑数据网格。当用户编辑单元格时,我希望能够将更新发布到后端服务,如果请求成功更新网格,如果没有撤消用户的更改并显示错误。

我从几个不同的角度解决了这个问题,但还没有找到满足我所有要求的解决方案,而且我也很好奇实现这种功能的最佳实践是什么。

我的第一个想法是利用 cellValueChanged 事件。通过这种方法,我可以查看旧值和新值,然后调用我的服务来更新数据库。如果请求成功,那么一切都很好并且按预期工作。但是,如果请求由于某种原因失败,那么我需要能够撤消用户的更改。由于我可以访问旧值,因此我可以轻松地执行event.node.setDataValue(event.column, event.oldValue) 之类的操作来恢复用户的更改。但是,由于我再次更新网格,这实际上会再次触发 cellValueChanged 事件。我无法知道这是撤消用户更改的结果,因此我不必要地再次调用我的服务来更新数据,即使原始请求从未成功更新数据。

我还尝试使用自定义单元格编辑器在用户完成单元格编辑和网格实际更新之间进行切换。但是,似乎没有办法在这些类中的任何一个中集成异步方法,以便能够等待来自服务器的响应来决定是否实际应用用户的更改。例如。

isCancelBeforeStart(): boolean {
    this.service.updateData(event.data).subscribe(() => {
      return false;
    }, error => {
      return true;
    });
}

不起作用,因为此方法是同步的,我需要能够等待服务的响应,然后再决定是否取消编辑。

有什么我遗漏或没有考虑到的吗?或者另一种方法来解决这个问题以获得我想要的功能?我意识到使用专用的编辑/保存按钮可以更轻松地处理此问题,但理想情况下,我正在寻找一个交互式网格,它可以在用户进行更改时将更改保存到后端,并在出现问题时提供反馈。

非常感谢任何帮助/反馈!

【问题讨论】:

    标签: ag-grid ag-grid-angular


    【解决方案1】:

    我了解您想要做什么,并且我认为最好的方法是在您的每个可编辑列上使用“valueSetter”函数。

    使用 valueSetter,网格的值不会直接更新 - 您必须更新绑定的数据才能使其反映在网格中。

    当网格在编辑结束时调用 valueSetter 时,您可能希望以某种方式记录原始值,更新绑定数据(以便网格反映更改),然后启动后端保存,并立即从 valueSetter 函数返回。

    (重要的是从 valueSetter 函数立即返回以保持网格响应。由于来自网格的 valueSetter 调用是同步的,如果您尝试等待服务器响应,您将锁定网格同时您'正在等待。)

    然后,如果后端更新成功,则无事可做,如果失败,您可以更新绑定的数据以反映原始值。

    使用此方法,您将不会有监听 cellValueChanged 事件的问题。

    您可能必须处理的一个问题是,如果用户更改单元格值,然后在第一次后端保存返回之前再次更改它,该怎么办。

    【讨论】:

      【解决方案2】:
      onCellValueChanged: (event) => {
        if (event.oldValue === event.newValue) {
          return;
        }
        try {
          // apiUpdate(event.data)
        }
        catch {
          event.node.data[event.colDef.Field] = event.oldValue;
          event.node.setDataValue(event.column, event.oldValue);
        }
      }
      

      通过先将node.data上的值改回,当setDataValue()再次触发change事件时,oldValue和newValue现在实际上是一样的,函数返回,避免了相当慢的无限循环。

      我认为这是因为您直接在后台更改数据而没有 agGrid 注意到 node.data = ,然后通过调用 setDataValue 进行 agGrid 识别并重新呈现单元格的更改。从而欺骗 agGrid 的行为。

      【讨论】:

        【解决方案3】:

        我会建议一个比 StangerString 更好的方法,但值得称赞的是,这个想法来自他的方法。您可以通过执行以下操作绕过更改检测,而不是使用对 oldValue/newValue 的测试并允许事件被调用两次。

        event.node.data[event.colDef.field] = event.oldValue;
        event.api.refreshCells({ rowNodes: [event.node], columns: [event.column.colId] });
        

        这样做是直接将数据设置在 agggrid 使用的数据存储中,然后告诉它刷新该网格。这将防止必须再次调用 onCellValueChanged 事件。

        (如果你不使用 colIds,你可以使用该字段或传递整个列,我认为它们中的任何一个都可以)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-10-30
          • 1970-01-01
          • 2021-02-17
          • 2018-04-30
          • 2020-12-02
          • 2015-03-02
          • 2020-08-21
          相关资源
          最近更新 更多