Миграция на Tabbed Application Mode

При добавлении дополнения Tabbed Application Mode встроенная навигация Vaadin отключается. В результате события навигации, такие как BeforeEnterEvent и AfterNavigationEvent, больше не отправляются экранам. Соответственно, вам может потребоваться переработать экраны, которые полагаются на эти события.

Чтобы упростить переработку, базовый класс View предоставляет метод processBeforeEnterInternal(), принимающий BeforeEnterEvent в качестве аргумента.

Обычные экраны

Например, рассмотрим экран с обязательным параметром маршрута, который используется для поиска данных, необходимых для дальнейшей работы:

@Route(value = "role-assignment/:username", layout = DefaultMainViewParent.class)   (1)
@ViewController(id = "RoleAssignmentView")
@ViewDescriptor(path = "role-assignment-view.xml")
public class RoleAssignmentView extends StandardView {

    private UserDetails user;

    @Override
    public void beforeEnter(BeforeEnterEvent event) {
        findUser(event.getRouteParameters());   (2)
        super.beforeEnter(event);
    }

    private void findUser(RouteParameters routeParameters) {
        String username = routeParameters.get("username")
                .orElseThrow(() -> new IllegalStateException("Username not found"));    (3)

        String decodedUsername = urlParamSerializer.deserialize(String.class, username);

        user = userRepository.loadUserByUsername(decodedUsername);
    }
}
1 Маршрутизация к этому экрану выполняется по обязательному параметру.
2 Получает параметры маршрута и использует их для поиска экземпляра пользователя.
3 Получает конкретный параметр маршрута и загружает экземпляр пользователя.

Чтобы этот экран работал внутри вкладки, переопределите метод processBeforeEnterInternal() и вызовите в нем метод findUser:

@Override
protected void processBeforeEnterInternal(BeforeEnterEvent event) {
    super.processBeforeEnterInternal(event);

    findUser(event.getRouteParameters());
}

Экраны деталей

Экран деталей предоставляет два метода для инициализации редактируемой сущности:

  • setupEntityToEdit(String) - вызывается при открытии экрана деталей через навигацию, когда редактируемая сущность загружается по ее ID, переданному в качестве параметра маршрута.

  • setupEntityToEdit(Entity) - вызывается при открытии экрана деталей в диалоговом окне, когда редактируемая сущность передается напрямую.

Рассмотрим пример, в котором экран деталей содержит пользовательский код, инициализирующий редактируемую сущность на основе параметра маршрута:

@Override
protected void initExistingEntity(String serializedEntityCode) {
    String code = urlParamSerializer.deserialize(String.class, serializedEntityCode);
    ResourceRole roleByCode = roleRepository.findRoleByCode(code);

    ResourceRoleModel resourceRoleModel = roleModelConverter.createResourceRoleModel(roleByCode);

    childRolesDc.mute();
    childRolesDc.setItems(loadChildRoleModels(resourceRoleModel));
    childRolesDc.unmute();

    ResourceRoleModel merged = dataContext.merge(resourceRoleModel);
    roleModelDc.setItem(merged);
}

В приведенном выше примере фактический экземпляр редактируемой сущности получается путем преобразования данных, хранящихся в базе данных, которые загружаются по id, переданному в качестве параметра маршрута. Поскольку этот экран не предназначен для открытия в диалоговом окне, в нем отсутствует соответствующий код для обработки напрямую переданного экземпляра сущности. Чтобы этот экран мог работать внутри вкладки, переопределите метод setupEntityToEdit() и предоставьте пустую реализацию:

@Override
protected void setupEntityToEdit(ResourceRoleModel entityToEdit) {
    // do nothing
}