Поведение двойного щелчка прослушивателя элемента Vaadin

Я работаю над приложением vaadin. Я предоставил левый одиночный щелчок и левый двойной щелчок в строке сетки через список кликов по элементам. В случае одиночного щелчка левой кнопкой мыши он работает правильно, но проблема в том, что всякий раз, когда я делаю двойной щелчок левой кнопкой мыши по сетке, листнер вызывается 3 раза, т.е.

  • Один щелчок

  • Один щелчок, затем

  • Двойной щелчок

    При первом вызове выбранный элемент правильный, но при втором и третьем вызове выбранный элемент недействителен. Кроме того, иногда возникает задержка при отправке действия клика на сервер (я не понимаю, почему). На моем компьютере он работает правильно, потому что клиент и сервер находятся на одном компьютере, но в реальной системе это выглядит так, как будто запрос от клиента (браузера) либо поздно доходит до сервера, либо вообще не доходит.
    Может ли кто-нибудь помочь мне в этом?
    Примечание. Модель выбора сетки — SingleSelection.

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

person Anam Qureshi    schedule 04.12.2020    source источник


Ответы (1)


Во-первых, существует потенциальная ошибка или ограничение: события click работают в браузерах так, что когда вы дважды щелкаете по элементу, на самом деле запускаются три события:

  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. Вот упрощенная разбивка: если на стороне сервера есть прослушиватель для определенного события, такого как щелчок:

  • Если текущего запроса нет, RPC отправляется на сервер сразу же, как только событие перехватывается в браузере. Итак, при первом нажатии двойного щелчка происходит > бум, отправляется на сервер
  • Если имеется текущий запрос, все события на стороне клиента, которые должны быть отправлены на сервер, помещаются в очередь, а события очереди отправляются на сервер после получения предыдущего ответа.

Как вы заметили, здесь может играть роль сетевая задержка — если цикл запрос-ответ очень быстрый, вы можете даже отправить три отдельных запроса к серверу; в медленной сети может пройти заметная задержка после активации первого прослушивателя на стороне сервера, прежде чем активируется второй.

Итак: хотя на сервере, казалось бы, имеет смысл сделать вывод, что в случае триплета с одним-единственным-двойным логическим событием будет только одно событие двойного щелчка, то, что сервер обычно получает первым, - это только одно событие одиночного щелчка. , в то время как событие второго щелчка и событие двойного щелчка, возможно, ожидают очереди в браузере. У сервера нет возможности узнать, что на самом деле это был двойной щелчок. Если нужно внести исправления, это нужно сделать на клиентской стороне реализации Grid; Я бы порекомендовал создать тикет GitHub об этом.

Далее, поскольку у вас есть сетка, в которой можно выбирать строки, первый щелчок по элементу выбирает его, второй щелчок отменяет его выбор. Здесь я бы рекомендовал использовать сетку с множественным выбором, так как там выбор не связан с щелчком по строке, а происходит путем установки флажка. Таким образом, вы все еще можете иметь прослушиватель кликов в строке и выбор, который не будет отменен случайно. Вам просто нужно убедиться, что предыдущий выбор очищается при выборе новой строки; это можно сделать в прослушивателе выбора.

person ollitietavainen    schedule 05.05.2021