Передача значений между классами в Vaadin

#vaadin #vaadin-flow #vaadin14

Вопрос:

Это может быть больше похоже на вопрос Java, но как бы вы получили доступ к значениям (скажем, из текстового поля) данного представления/класса из другого класса? Например, если в главном представлении было текстовое поле t1, и я хотел получить его текущее значение для вычисления в другом классе. И есть ли здесь более специфичный для Ваадина подход?

Комментарии:

1. В вашем примере, что запускает выполнение вычисления?

2. @BasilBourque прослушиватель изменения значения флажка. следующий шаг, который я пытаюсь реализовать, — это затем извлечь значение текстового поля, выполнить вычисление и визуализировать его в главном представлении

3. Я использую POJO для каждого представления и передаю это POJO во всем потоке этого представления.

Ответ №1:

Это может зависеть от конкретного варианта использования. Поскольку вы упомянули значение текстового поля, я предполагаю, что это значение еще не сохранено в базе данных, оно пока только в пользовательском интерфейсе -> Я исключаю службы singleton spring.

Несколько идей:

  1. Если основной вид и разные классы являются вложенными компонентами, и это жизнеспособно и не очень сложно для многих классов… затем, вероятно, передайте это по пути при создании подкомпонента. Это наивное решение — оно может стать довольно запутанным.
     MainView() {
        var t1 = new TextField();
        var d = new Different(t1);
    }
     
  2. Стреляйте и слушайте события компонента Vaadin. Если вы хотите действительно ослабить связь, наиболее универсальным было бы использовать экземпляр пользовательского интерфейса в качестве шины событий.
     // listen in different class
    ComponentUtil.addListener(attachEvent.getUI(), CloseMenuEvent.class, e -> closeMenu());
    // fire change in MainView
    ComponentUtil.fireEvent(ui, new CloseMenuEvent(ui))
     
  3. Более конкретная версия номера 2. состоит в том, чтобы передать основной ValueChangeListener вид t1 в другой класс.
     MainView() {
        var t1 = new TextField();
        var d = new DifferentClass();
        t1.addValueChangeListener(d::t1Changed)
        add(t1, d);
    }
     
  4. Извлеките общее поле для третьей стороны, для третьего класса. Используйте @UIScoped компонент spring ( @SpringComponent , @Service ,…), который будет содержать это поле, и внедрите его как в MainView, так и в другой класс.
     @Route
    public class MainView extends VerticalLayout {
        public MainView(Model m, Different d) {
            add(m.t1, d);
        }
    }
    
    @Scope(SCOPE_PROTOTYPE)
    public class Different extends Component {
        public Different(Model m) {
            // something with m.t1
        }
    }
    
    @UIScoped
    public class Model {
        public final TextField t1 = new TextField(); // TODO use getter
    }
     

    Вы можете изменить 4-й подход, сохранив строку в модели и установив прослушиватель изменения значения, который обновляет ее.

Комментарии:

1. спасибо за этот подробный список! сначала я попробую № 3, а затем продолжу