3.5.12.3. Использование механизма навигации и истории просмотров URL

Этот раздел содержит примеры использования механизма навигации и истории просмотров URL.

Предположим, у нас есть сущность Task и экран TaskInfo с информацией о выбранной задаче.

Контроллер экрана TaskInfo содержит аннотацию @Route для указания маршрута к экрану:

package com.company.demo.web.navigation;

import com.haulmont.cuba.gui.Route;
import com.haulmont.cuba.gui.screen.Screen;
import com.haulmont.cuba.gui.screen.UiController;
import com.haulmont.cuba.gui.screen.UiDescriptor;

@Route("task-info")
@UiController("demo_TaskInfoScreen")
@UiDescriptor("task-info.xml")
public class TaskInfoScreen extends Screen {
}

В результате пользователь может открыть экран, введя http://localhost:8080/app/#main/task-info в адресной строке:

url screen by route

Когда экран открыт, адрес также содержит метку состояния.

Отображение состояния на URL

Предположим, на экране TaskInfo отображается информация об одной задаче и присутствует элемент управления для переключения задач. Вы можете отобразить просматриваемую задачу в адресной строке, чтобы иметь возможность скопировать URL, а затем открыть экран для этой конкретной задачи, вставив URL в адресную строку.

Следующий код реализует отображение выбранной задачи на URL:

package com.company.demo.web.navigation;

import com.company.demo.entity.Task;
import com.google.common.collect.ImmutableMap;
import com.haulmont.cuba.gui.Route;
import com.haulmont.cuba.gui.UrlRouting;
import com.haulmont.cuba.gui.components.Button;
import com.haulmont.cuba.gui.components.LookupField;
import com.haulmont.cuba.gui.screen.*;
import com.haulmont.cuba.web.sys.navigation.UrlIdSerializer;

import javax.inject.Inject;

@Route("task-info")
@UiController("demo_TaskInfoScreen")
@UiDescriptor("task-info.xml")
@LoadDataBeforeShow
public class TaskInfoScreen extends Screen {

    @Inject
    private LookupField<Task> taskField;

    @Inject
    private UrlRouting urlRouting;

    @Subscribe("selectBtn")
    protected void onSelectBtnClick(Button.ClickEvent event) {
        Task task = taskField.getValue(); (1)
        if (task == null) {
            urlRouting.replaceState(this); (2)
            return;
        }
        String serializedTaskId = UrlIdSerializer.serializeId(task.getId()); (3)

        urlRouting.replaceState(this, ImmutableMap.of("task_id", serializedTaskId)); (4)
    }
}
1 - получить текущую задачу из LookupField
2 - удалить параметры URL, если задача не выбрана
3 - сериализовать идентификатор задачи с помощью вспомогательного класса UrlIdSerializer
4 - заменить текущее состояние URL новым, содержащим в качестве параметра сериализованный идентификатор задачи.

В результате URL приложения изменяется, когда пользователь выбирает задачу и нажимает кнопку Select Task:

url reflection state
UrlParamsChangedEvent

Теперь давайте выполним последнее требование: когда пользователь вводит URL с маршрутом и параметром task_id, приложение должно показать экран с соответствующей выбранной задачей. Ниже приведен полный код контроллера экрана.

package com.company.demo.web.navigation;

import com.company.demo.entity.Task;
import com.google.common.collect.ImmutableMap;
import com.haulmont.cuba.core.global.DataManager;
import com.haulmont.cuba.gui.Route;
import com.haulmont.cuba.gui.UrlRouting;
import com.haulmont.cuba.gui.components.Button;
import com.haulmont.cuba.gui.components.LookupField;
import com.haulmont.cuba.gui.navigation.UrlParamsChangedEvent;
import com.haulmont.cuba.gui.screen.*;
import com.haulmont.cuba.web.sys.navigation.UrlIdSerializer;

import javax.inject.Inject;
import java.util.UUID;

@Route("task-info")
@UiController("demo_TaskInfoScreen")
@UiDescriptor("task-info.xml")
@LoadDataBeforeShow
public class TaskInfoScreen extends Screen {

    @Inject
    private LookupField<Task> taskField;

    @Inject
    private UrlRouting urlRouting;

    @Inject
    private DataManager dataManager;

    @Subscribe
    protected void onUrlParamsChanged(UrlParamsChangedEvent event) {
        String serializedTaskId = event.getParams().get("task_id"); (1)

        UUID taskId = (UUID) UrlIdSerializer.deserializeId(UUID.class, serializedTaskId); (2)

        taskField.setValue(dataManager.load(Task.class).id(taskId).one()); (3)
    }

    @Subscribe("selectBtn")
    protected void onSelectBtnClick(Button.ClickEvent event) {
        Task task = taskField.getValue();
        if (task == null) {
            urlRouting.replaceState(this);
            return;
        }
        String serializedTaskId = UrlIdSerializer.serializeId(task.getId());

        urlRouting.replaceState(this, ImmutableMap.of("task_id", serializedTaskId));
    }
}
1 - получить значение параметра из UrlParamsChangedEvent
2 - десериализовать идентификатор задачи
3 - загрузить экземпляр задачи и установить его в поле LookupField