【问题标题】:Vaadin item click listener double click behaviourVaadin 项目点击监听器双击行为
【发布时间】:2021-03-16 12:04:59
【问题描述】:

我正在开发一个 vaadin 应用程序。我通过项目单击列表器在网格行上提供了左键单击和左键双击操作。如果左键单击它可以正常工作,但问题是每当我在网格上左键双击时,listner 都会被调用 3 次,即

  • 单击

  • 单击,然后

  • 双击

    在第一次调用时,所选项目是正确的,但在第二次和第三次调用时,所选项目为空。此外,有时将点击操作发送到服务器会有延迟(我不明白为什么)。在我的机器上它工作正常,因为客户端和服务器都在同一台机器上,但在实际系统上,看起来来自客户端(浏览器)的请求要么延迟到服务器,要么根本没有到达。
    任何人都可以帮助我吗?
    注意- 网格选择模型是 SingleSelection。

     @Override
     public void itemClick(final ItemClick<PersonData> itemClickEvent) {
         final PersonData data = itemClickEvent.getItem();
         if (itemClickEvent.getMouseEventDetails().isDoubleClick()) {
              //some logic
             } else {
              //some logic
         }
     }
    

【问题讨论】:

    标签: client-server vaadin onitemclicklistener double-click vaadin8


    【解决方案1】:

    首先,有一个潜在的错误或限制:点击事件在浏览器中的工作方式是,当你双击一个元素时,它实际上会触发三个事件:

    1. 第一次点击后的单击事件
    2. 第二次单击后的第二次单击事件
    3. 双击事件(假设第二次点击在第一次之后发生得足够快)

    您可以像这样在纯 HTML 文档中对此进行测试:

    <!DOCTYPE html>
    <html>
    <body>
    
    <button ondblclick="d()" onclick="s()">Double-click here</button>
    
    <p id="demo"></p>
    
    <script>
    function d() {
      document.getElementById("demo").innerHTML += "Double";
    }
    function s() {
    document.getElementById("demo").innerHTML += "Single";
    }
    </script>
    
    </body>
    </html>
    

    您会注意到,如果您双击该按钮,它将打印“SingleSingleDouble”。所以框架的服务器端事件以一种幼稚的方式反映了浏览器事件。

    由于客户端-服务器 RPC 调用在 Vaadin 中的工作方式,很难创建一个服务器端修复程序以使服务器端事件以更直观的方式运行。这是一个简化的细分: 如果有一个特定事件的服务器端监听器,比如“click”:

    • 如果没有正在进行的请求,则在浏览器中捕获事件时立即向服务器发送 RPC。所以当第一次点击双击发生时->咚,发送到服务器
    • 如果一个正在进行的请求,任何应该发送到服务器的客户端事件都被放置在一个队列中,一旦前一个响应到达,队列的事件就会被发送到服务器

    正如您所注意到的,网络延迟可能会在这里发挥作用 - 如果请求-响应周期非常快,您甚至可能最终向服务器发出三个单独的请求;在慢速网络上,在第一个服务器端监听器激活之后,第二个监听器激活之前可能需要明显的延迟。

    所以:虽然在服务器上推断在“单-单-双”三元组的情况下“逻辑”事件只是一个双击事件似乎是有意义的,但服务器通常首先收到的是只有一个单击事件,而第二个单击事件和双击事件可能在浏览器的队列中等待。服务器无法知道它实际上是双击。如果需要修复,则需要在 Grid 实现的客户端完成;我建议创建一个关于它的 GitHub 票证。

    接下来,因为您有 Grid 可以选择行,所以第一次单击该项目会选择它,第二次单击会取消选择它。在这里,我建议使用多选网格,因为选择不与单击行相关联,而是通过选中复选框发生。这样,您仍然可以在该行上有一个单击侦听器和一个不会意外取消选择的选择。您只需要确保在选择新行时清除先前的选择;这可以在选择侦听器中完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-27
      • 1970-01-01
      • 1970-01-01
      • 2018-06-06
      • 1970-01-01
      • 1970-01-01
      • 2018-10-02
      • 2013-04-04
      相关资源
      最近更新 更多