Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Параметры маршрута

Параметр маршрута — изменяемая часть адреса. Чтобы открыть статью номер 5 на редактирование, удобно иметь адрес /posts/5: его можно сохранить в закладки и отправить коллеге. Vaadin берёт параметр из адреса, превращает в нужный тип и передаёт экрану до того, как тот появится на странице.

HasUrlParameter

Сделаем так, чтобы форма из главы про данные умела и создавать, и редактировать:

// src/main/java/com/example/blog/views/PostFormView.java (изменённые части)
@Route("posts")
@PageTitle("Статья")
public class PostFormView extends VerticalLayout implements HasUrlParameter<Long> {
 
    private final H2 heading = new H2();
    private Post post;
 
    @Override
    public void setParameter(BeforeEvent event, @OptionalParameter Long id) {
        if (id == null) {
            post = new Post();
            post.setPublishedOn(LocalDate.now());
            heading.setText("Новая статья");
        } else {
            post = service.findById(id).orElse(null);
            if (post == null) {
                event.forwardTo(PostListView.class);
                return;
            }
            heading.setText("Редактирование");
        }
        binder.readBean(post);
    }
}

heading добавьте первым в add(...) конструктора, а сервис сохраните в поле service. Импорты из com.vaadin.flow.router: HasUrlParameter, BeforeEvent, OptionalParameter; ещё com.vaadin.flow.component.html.H2.

АдресЧто откроется
/postsПустая форма «Новая статья», id равен null
/posts/1Форма со статьёй «Привет, Vaadin»
/posts/999Такой статьи нет — переход на список
/posts/abcНе число — страница «Could not navigate to 'posts/abc'»

setParameter вызывается при каждом переходе на экран, раньше, чем экран показан. @OptionalParameter разрешает адрес без параметра.

Переход с параметром

В таблице откроем статью по двойному клику:

// src/main/java/com/example/blog/views/PostListView.java (фрагмент конструктора)
grid.addItemDoubleClickListener(event ->
        getUI().ifPresent(ui -> ui.navigate(PostFormView.class, event.getItem().getId())));

Двойной клик по строке «Таблицы и формы» откроет /posts/2 с заполненной формой. Второй аргумент navigate — значение параметра, Vaadin сам подставит его в адрес.

Шаблоны маршрутов

Если параметров несколько или они стоят в середине адреса, используйте шаблон. Имена параметров пишутся через двоеточие:

// src/main/java/com/example/blog/views/CommentsView.java
package com.example.blog.views;
 
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.BeforeEnterEvent;
import com.vaadin.flow.router.BeforeEnterObserver;
import com.vaadin.flow.router.Route;
 
@Route("posts/:postId/comments")
public class CommentsView extends VerticalLayout implements BeforeEnterObserver {
 
    private final H2 heading = new H2();
 
    public CommentsView() {
        add(heading);
    }
 
    @Override
    public void beforeEnter(BeforeEnterEvent event) {
        long postId = event.getRouteParameters().getLong("postId").orElseThrow();
        heading.setText("Комментарии к статье " + postId);
    }
}

Адрес /posts/2/comments покажет «Комментарии к статье 2». В шаблоне можно ограничить параметр регулярным выражением: :postId([0-9]+).

Параметры запроса

Часть адреса после ? читается так:

// src/main/java/com/example/blog/views/CommentsView.java (фрагмент beforeEnter)
String sort = event.getLocation().getQueryParameters()
        .getSingleParameter("sort").orElse("new");

Для /posts/2/comments?sort=old переменная sort будет old, без параметра — new.

Частая ошибка

Параметр объявлен без @OptionalParameter, а кнопка «Новая статья» переходит без него:

// src/main/java/com/example/blog/views/PostListView.java (не работает без @OptionalParameter)
ui.navigate(PostFormView.class);

Нажатие кнопки заканчивается исключением:

java.lang.IllegalArgumentException: Navigation target 'com.example.blog.views.PostFormView' requires a parameter.

Пометьте параметр @OptionalParameter или передавайте значение во втором аргументе navigate.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.