2015-08-28 1 views
3

Извините, но у меня должен быть умственный лапсус прямо сейчас, потому что я не вижу, где проблема, и должен быть тривиальным. Я подготовил простой сценарий, в котором я привязываю поле к свойству bean с помощью BeanFieldGroup, и когда я нажимаю кнопки «Изменить» и «Сброс», модель устанавливается с правильными значениями, но текстовое поле в пользовательском интерфейсе не обновляется. Я использую Vaadin4Spring, но не должен быть проблемой.Обновление после привязки данных не обновляет содержимое в UI

import com.vaadin.data.fieldgroup.BeanFieldGroup; 
import com.vaadin.navigator.View; 
import com.vaadin.navigator.ViewChangeListener; 
import com.vaadin.spring.annotation.SpringView; 
import com.vaadin.ui.Button; 
import com.vaadin.ui.Notification; 
import com.vaadin.ui.TextField; 
import com.vaadin.ui.VerticalLayout; 

import java.io.Serializable; 

@SpringView(name = "test") 
public class TestView extends VerticalLayout implements View { 

    private TextField txtTest = new TextField("Test"); 
    private Button btnChange = new Button("Click!"); 
    private Button btnReset = new Button("Reset"); 

    private TestBean testBean = new TestBean(); 

    public TestView() { 
     txtTest.setImmediate(true); 

     addComponent(txtTest); 
     addComponent(btnChange); 
     addComponent(btnReset); 

     BeanFieldGroup<TestBean> binder = new BeanFieldGroup<>(TestBean.class); 
     binder.setItemDataSource(testBean); 
     binder.setBuffered(false); 
     binder.bind(txtTest, "text"); 

     initComponents(); 
    } 

    private void initComponents() { 
     btnChange.addClickListener(new Button.ClickListener() { 
      @Override 
      public void buttonClick(Button.ClickEvent event) { 
       testBean.setText("Hello world!"); 
      } 
     }); 

     btnReset.addClickListener(new Button.ClickListener() { 
      @Override 
      public void buttonClick(Button.ClickEvent event) { 
       testBean.setText(""); 
      } 
     }); 
    } 

    @Override 
    public void enter(ViewChangeListener.ViewChangeEvent event) { 
     Notification.show("Test"); 
    } 

    public class TestBean implements Serializable { 

     private String text; 

     public TestBean() { 
      text = ""; 
     } 

     public String getText() { 
      return text; 
     } 

     public void setText(String text) { 
      this.text = text; 
     } 

    } 

} 

ответ

1

Вы вызываете боба сеттер непосредственно и потому, что Java не дает какой-либо способ слушать такого рода изменения, свойство Vaadin (или TextField) не знает, что значение было изменено. Если вы измените значение через свойство Vaadin говоря

binder.getItemDataSource().getItemProperty("text").setValue("new value"); 

тогда вы увидите «новое значение» на TextField, и потому, что буферизация отключена, testBean.getText() также возвращает «новое значение».

+0

Спасибо @Henri, Марко уже посоветовал мне об этом. Мой немедленный вопрос заключается в необходимости иметь эти текстовые имена свойств. Не существует ли более склонный к ошибкам способ привязки и изменения значений? – frandevel

+0

Я использовал Пектин с GWT, чтобы избежать всего этого. Разве нет что-то подобное в Ваадине? – frandevel

+0

@frandevel Вы можете, например, добавить генератор кода в свой проект, который генерирует константы из getters/and seters. Когда геттеры и сеттеры удаляются или переименовываются, вы получаете ошибки времени компиляции, потому что генератор кода больше не генерирует используемые константы. –

2

Ближайшая вещь, которую я нашел, это binder.discard(), которая заставляет все связанные поля перечитать ее значение из компонента. Да, его еще нужно называть вручную, но все же гораздо менее болезненным, чем getItemDataSource().getItemProperty(...).setValue(...). Если есть какие-либо проблемы с этим подходом грубой силы, то, конечно, можно называть Field.discard() непосредственно на полях, которые должны быть затронуты.