Как обновить 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
    }
}

Надеюсь, что это поможет вам:)

Другие вопросы по тегам