数据绑定后更新不更新 UI 中的内容
Updating after data binding does not update content in UI
抱歉,我现在一定是脑子出了问题,因为我看不出问题出在哪里,应该是微不足道的。我准备了一个简单的场景,我使用 BeanFieldGroup 将字段绑定到 bean 属性,当我单击“更改”和“重置”按钮时,模型设置了正确的值,但 UI 没有被更新。
我正在使用 Vaadin4Spring,但应该不是问题所在。
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;
}
}
}
您正在直接调用 bean setter,因为 Java 没有提供任何方式来监听那种变化,所以 Vaadin 属性(或 TextField)没有不知道该值已更改。如果您通过 Vaadin 属性 通过说
更改值
binder.getItemDataSource().getItemProperty("text").setValue("new value");
然后您会在 TextField
上看到 "new value",并且由于禁用了缓冲,因此 testBean.getText()
也会 returns "new value"。
我发现的最接近的是 binder.discard()
,它强制所有绑定字段从 bean 重新读取它的值。是的,它仍然需要手动调用,但仍然远没有 getItemDataSource().getItemProperty(...).setValue(...)
痛苦。如果对这种蛮力方法有任何顾虑,那么当然可以直接在应该受到影响的字段上调用 Field.discard()
。
抱歉,我现在一定是脑子出了问题,因为我看不出问题出在哪里,应该是微不足道的。我准备了一个简单的场景,我使用 BeanFieldGroup 将字段绑定到 bean 属性,当我单击“更改”和“重置”按钮时,模型设置了正确的值,但 UI 没有被更新。 我正在使用 Vaadin4Spring,但应该不是问题所在。
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;
}
}
}
您正在直接调用 bean setter,因为 Java 没有提供任何方式来监听那种变化,所以 Vaadin 属性(或 TextField)没有不知道该值已更改。如果您通过 Vaadin 属性 通过说
更改值binder.getItemDataSource().getItemProperty("text").setValue("new value");
然后您会在 TextField
上看到 "new value",并且由于禁用了缓冲,因此 testBean.getText()
也会 returns "new value"。
我发现的最接近的是 binder.discard()
,它强制所有绑定字段从 bean 重新读取它的值。是的,它仍然需要手动调用,但仍然远没有 getItemDataSource().getItemProperty(...).setValue(...)
痛苦。如果对这种蛮力方法有任何顾虑,那么当然可以直接在应该受到影响的字段上调用 Field.discard()
。