Обработчик выбора TabLayoutPanel запускается несколько раз
В настоящее время я работаю с GWT TabLayoutPanel и получил некоторые проблемы. Мое приложение использует Действия и Места для управления историей браузера. С TabLayoutPanel я пытаюсь сохранить вкладки в истории, выполняя placeController.goTo() в событии onSelectionHandler() (чтобы я мог вернуться в браузер). Я обновляю список вкладок, делая tabLayoutPanel.clear(). Проблема в том, что tabPanel.clear() запускает selectionHandler несколько раз, и, таким образом, мои Places запускаются много раз. Чтобы исправить это поведение, я должен был добавить локальное включение и отключение SelectionHandler, но мне это не кажется подходящим.
Ниже приведены примеры кода. Я использую метод addEvents, чтобы обновить список вкладок для некоторых событий.
@UiField
TabLayoutPanel tabPanel;
private Boolean enabledSelectionHandler = true;
...
public EventsPageImpl(EventBus bus, final PlaceController placeController) {
initWidget(uiBinder.createAndBindUi(this));
tabPanel.addSelectionHandler(new SelectionHandler<Integer>() {
@Override
public void onSelection(SelectionEvent<Integer> event) {
if (enabledSelectionHandler) {
if (eventsList.size() > 0 && event.getSelectedItem() != 0) {
placeController.goTo(new EventsPlace(eventsList.get(event.getSelectedItem() - 1).getId().toString()));
} else {
placeController.goTo(new EventsPlace(null));
}
}
}
});
...
}
@Override
public void addEvents(List<ClientEvent> events) {
enabledSelectionHandler = false;
tabPanel.clear();
tabPanel.add(new EventsTab(presenter), CommonMessages.INSTANCE.createNewEvent());
if (eventsList.size() == 0 && events.size() > 0) {
for (ClientEvent event : events) {
eventsList.add(event);
}
}
for (ClientEvent event : eventsList) {
tabPanel.add(new EventsTab(event, presenter), event.getTitle());
}
enabledSelectionHandler = true;
}
Есть ли какой-либо другой правильный путь без использования локального enabledSelectionHandler для предотвращения многократного запуска SelectionHandler?
1 ответ
Поведение панели TabLayoutPanel является правильным. Когда вы вызываете clear TabLayoutPanel, удаляйте каждую вкладку одну за другой. При удалении вкладки выбирается последняя вкладка -> отправка события выбора. Поэтому, когда вы очищаете TabLayoutPanel с n элементами, у вас должно появиться событие выбора n-1.
Я думаю, что ваше решение хорошо, но, возможно, вы могли бы использовать регистрацию обработчика, чтобы включить / отключить прослушивание события
final HandlerRegistration registration = tabPanel.addSelectionHandler(this);
registration.removeHandler();
Также рассмотрите возможность использования BeforeSelectionEvent для включения / отключения события.