Обновление данных в открытой вкладке.

Есть открытая вкладка со списком покупателей (из квик туториала)
Есть другая вкладка FOO, на которой при нажатии кнопки создается покупатель "foo"
Но чтобы обновить данные на странице со списком покупателей приходится снова переходить на эту страницу из меню навигации.
Даже рефреш страницы из браузера не помогает, ну тут в приципе понятно spa, чего бы оно обновлялось.
Собственно как правильно реализовать подобное обновление?

Здравствуйте,

Для коммуникации между вкладками приложения одной страницы браузера можно использовать Google EventBus (он входит в состав библиотеки Guava, подключенной в платформе).

  1. Нужно расширить главное окно приложения и объявить в нём экземпляр объекта EventBus.

public class ExtAppMainWindow extends AppMainWindow {
    private EventBus eventBus = new EventBus();

    public void subscribe(Object listener) {
        eventBus.register(listener);
    }

    public void unsubscribe(Object listener) {
        eventBus.register(listener);
    }

    @SuppressWarnings("unchecked")
    public void triggerEvent(Object event) {
        eventBus.post(event);
    }
}
  1. В качестве объектов-событий используются POJO вида:

public class ClientAddedEvent {
    private final Client client;

    public ClientAddedEvent(Client client) {
        this.client = client;
    }

    public Client getClient() {
        return client;
    }
}
  1. В экранах, которые хотят реагировать на события, мы объявляем методы, принимающие объекты - события. Например, в экране заказа мы хотим узнать о новом созданном клиенте и обновить список клиентов для поля Клиент.

public class OrderEdit extends AbstractEditor<Order> {
    @Inject
    private CollectionDatasource<Client, UUID> clientsDs;

    @Override
    public void init(Map<String, Object> params) {
        super.init(params);

        // get main window
        ExtAppMainWindow mainWindow = ((ExtAppMainWindow) App.getInstance().getTopLevelWindow());
        mainWindow.subscribe(this);

        addCloseListener(actionId ->
                mainWindow.unsubscribe(this)
        );
    }

    // Google EventBus event handler
    @Subscribe
    public void onClientAdded(ClientAddedEvent event) {
        // refresh clients ds
        clientsDs.refresh();
    }
}
  1. В экранах, которые хотят сообщить о событии, мы оповещаем EventBus:

public class ClientBrowse extends AbstractLookup {
    @Named("clientsTable.create")
    private CreateAction clientsTableCreate;

    @Override
    public void init(Map<String, Object> params) {
        super.init(params);

        clientsTableCreate.setAfterCommitHandler(entity -> {
            ExtAppMainWindow topLevelWindow = ((ExtAppMainWindow) App.getInstance().getTopLevelWindow());
            topLevelWindow.triggerEvent(new ClientAddedEvent((Client) entity));
        });
    }
}

Полный код примера доступен на GitHub: https://github.com/cuba-labs/web-screens-eventbus

В этом примере, если открыт редактор заказа и пользователь создаёт нового клиента, то список клиентов в редакторе заказа обновляется. Это работает только для редактирования/создания из одного окна браузера, поскольку обмен событиями ведётся через главное окно приложения.

1 симпатия

Недавно, в версии 6.7 мы добавили поддержку публикации событий в экранах на базе Spring Framework. Поэтому, больше не требуется отдельно настраивать EventBus из Guava. См. https://doc.cuba-platform.com/manual-6.8-ru/events.html#ui_events

2 симпатии