Как обновить Vaadin Grid после нажатия?
Я пытаюсь обновить сетку в Vaadin после изменения сетки из другого экземпляра пользовательского интерфейса.
Чтобы уточнить, у меня есть два разных экземпляра пользовательского интерфейса, UI1 и UI2 (вкладки из двух разных браузеров). Эти экземпляры пользовательского интерфейса содержат представление, которое содержит сетку, состоящую из объектов Contact, которые имеют различные свойства, такие как имя, возраст, пол...
Я добавляю контакт в сетку из UI1 и хочу, чтобы UI2 мгновенно видел обновленную сетку, не обновляя ее.
Для этого я знаю, что должен использовать Vaadin Push, который я уже настроил с помощью класса Broadcaster. у меня есть receiveBroadcast()
метод в моем классе пользовательского интерфейса, который будет обновлять пользовательский интерфейс всякий раз, когда класс View отправляет широковещательную передачу в пользовательский интерфейс, используя broadcast()
метод. Часть моего пользовательского интерфейса выглядит так:
@Title("Contact Book")
@Theme("reindeer")
@Push
public class UserInterface extends UI implements BroadcastListener{
private Navigator navigator;
@Override
protected void init(VaadinRequest request){
navigator = new Navigator(this, this);
navigator.addView(ContactBookView.NAME, new ContactBookView());
Broadcaster.register(this);
}
@Override
public void detach(){
Broadcaster.unregister(this);
super.detach();
}
@Override
public void receiveBroadcast(Grid grid) {
access(()->{
// update grid here
Notification.show("Grid updated", Notification.Type.TRAY_NOTIFICATION);
});
}
}
И мой класс Broadcaster такой же в этой ссылке (я просто немного изменил методы, чтобы передать сетку в качестве параметра)
Затем в моем классе ContactBookView я звоню Broadcaster.broadcast(grid)
метод после добавления или изменения элемента, чтобы я мог как-то обновить сетку в своем классе пользовательского интерфейса access()
метод, но ничего, что я пробовал, похоже, не работает. Я знаю, что push работает, потому что я вижу сообщение "Grid updated" во всех экземплярах пользовательского интерфейса при получении широковещательной рассылки.
Я попытался удалить представление и повторно инициализировать
navigator.removeView(ContactBookView.NAME);
navigator.addView(ContactBookView.NAME, new ContactBookView());
Пытался полностью очистить сетку и пополнить
grid.removeAllColumns();
grid.setContainerDataSource(container);
Пытался заставить сетку обновляться, используя этот уродливый обходной путь
grid.setContainerDataSource(grid.getContainerDataSource());
Попытка выполнить запрос JavaScript для принудительной синхронизации интерфейса
JavaScript.getCurrent().execute("javascript:vaadin.forceSync();");
Но ничего из этого не сработало. Может я что-то не так делаю? К вашему сведению, моя версия Vaadin - 7.5.0.
Буду признателен за любые отзывы или советы,
Благодарю.
2 ответа
Мне удалось решить проблему путем повторного перехода к текущему представлению после его повторной инициализации. Окончательный метод доступа к интерфейсу выглядит следующим образом:
public void receiveBroadcast() {
access(()->{
navigator.removeView(ContactBookView.NAME);
navigator.addView(ContactBookView.NAME, new ContactBookView());
navigator.navigateTo(ContactBookView.NAME);
Notification.show("Grid updated", Notification.Type.TRAY_NOTIFICATION);
});
При этом представление обновляется в фоновом режиме и передается в экземпляры пользовательского интерфейса без физического обновления.
Я уверен, что могут быть лучшие обходные пути, и этот кажется уродливым, но в настоящее время он удовлетворяет мои потребности. Тем не менее, я все равно оценил бы любой другой подход.
Если вы используете navigator.navigateTo(PortletUI.SOMEPAGE);
В somePageInstance должен вызываться первым
enter()
метод, пока вы будете приходить туда через навигатор, поэтому вы не можете попробовать обновить сетку там: о)
PortletUI:
public static final String SOMEPAGE = null;
Navigator navigator;
SomePage somePageInstance = null;
protected void init(VaadinRequest request) {
InitPortlet.initPortlet(this);
// Create a navigator to control the views
navigator = new Navigator(this, this);
somePageInstance = new SomePage();
navigator.addView(SOMEPAGE, somePageInstance);
SomePage:
public class SomePage extends SomePageDesign implements View{
//or you can give there navigator from portlet through constructor probably
Navigator navigator;
@Override
public void enter(ViewChangeEvent event) {
//needed for navigate to another page :)
navigator = event.getNavigator();
//Update grid
}
}
Надеюсь, что это поможет вам:)