1

我正在使用 Vaadin 14,为了避免在用户双击按钮而不是一次时多次发送请求,我正在调用setDisableOnClick(true)实例Button

对于某些按钮来说,这还不够:按钮仍然可以被多次点击。在 Chrome devtools 中检查 dom 时,我可以看到disableonclick为这些按钮设置了属性:

在此处输入图像描述

我怀疑这是调用事件处理程序的顺序的问题(应该在发送请求之前调用要禁用的处理程序)。

我宁愿不在服务器端设置布尔值来检查操作是否已执行。是否有另一种选择可以在单击后立即可靠地禁用按钮?

4

1 回答 1

2

这似乎是一个 Vaadin 错误。它不起作用的情况是按钮位于Dialog关闭然后重新打开的情况下。当您调用时setDisableOnClick(true),他们使用 hack 从服务器端添加事件侦听器:

/**
 * Initialize client side disabling so disabled if immediate on click even
 * if server-side handling takes some time.
 */
private void initDisableOnClick() {
    if (!disableOnClickConfigured) {
        getElement().executeJs("var disableEvent = function () {"
                + "if($0.getAttribute('disableOnClick')){"
                + " $0.setAttribute('disabled', 'true');" + "}" + "};"
                + "$0.addEventListener('click', disableEvent)");
        disableOnClickConfigured = true;
    }
}

当按钮被分离并重新连接时,这个事件处理程序就消失了。

不幸的是setDisableOnClick(true),重新打开对话框后再次调用将无济于事,因为disableOnClickConfigured已经设置为 true,因此将跳过此代码。

我看到三个选项:

  1. 当按钮重新连接时(对话框重新打开),通过反射将私有字段重置disableOnClickConfiguredfalse,然后setDisableOnClick(true)再次调用。
  2. 复制代码以添加客户端事件侦听器并在重新附加按钮时执行它。
  3. 通过用一个新按钮替换按钮,甚至在Dialog每次打开按钮时创建一个全新的实例来避免这个问题。

这是我选择的最后一个选项。这Dialog是一个 Spring bean,所以我使用 Prototype 范围并用 注入它ObjectFactory,然后在调用之前获取一个新实例open

于 2020-08-28T14:00:09.920 回答