summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorTeemu Suo-Anttila <tsuoanttila@users.noreply.github.com>2018-03-24 15:02:39 +0200
committerIlia Motornyi <elmot@vaadin.com>2018-03-24 15:02:39 +0200
commit00c3f2c37c104498e23bd8f25dfd5ab8ce65294b (patch)
tree86be279141ce928738b6b1ce4e77b109ee06a5c0 /server
parent3cd5e1a1dab61b8a6b328c0839211b6862d15521 (diff)
downloadvaadin-framework-00c3f2c37c104498e23bd8f25dfd5ab8ce65294b.tar.gz
vaadin-framework-00c3f2c37c104498e23bd8f25dfd5ab8ce65294b.zip
Fix ValueChangeListener order changes with Binder (#10745)
Fixes #9917
Diffstat (limited to 'server')
-rw-r--r--server/src/main/java/com/vaadin/data/Binder.java18
-rw-r--r--server/src/test/java/com/vaadin/data/BinderTest.java25
2 files changed, 35 insertions, 8 deletions
diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java
index 769ca74bed..f9e076e13f 100644
--- a/server/src/main/java/com/vaadin/data/Binder.java
+++ b/server/src/main/java/com/vaadin/data/Binder.java
@@ -982,8 +982,8 @@ public class Binder<BEAN> implements Serializable {
private boolean readOnly;
- // Not final since we temporarily remove listener while changing values
- private Registration onValueChange;
+ private final Registration onValueChange;
+ private boolean valueInit = false;
/**
* Contains all converters and validators chained together in the
@@ -1056,7 +1056,6 @@ public class Binder<BEAN> implements Serializable {
public void unbind() {
if (onValueChange != null) {
onValueChange.remove();
- onValueChange = null;
}
binder.removeBindingInternal(this);
binder = null;
@@ -1116,12 +1115,11 @@ public class Binder<BEAN> implements Serializable {
private void initFieldValue(BEAN bean) {
assert bean != null;
assert onValueChange != null;
- onValueChange.remove();
+ valueInit = true;
try {
getField().setValue(convertDataToFieldType(bean));
} finally {
- onValueChange = getField()
- .addValueChangeListener(this::handleFieldValueChange);
+ valueInit = false;
}
}
@@ -1139,6 +1137,11 @@ public class Binder<BEAN> implements Serializable {
*/
private void handleFieldValueChange(
ValueChangeEvent<FIELDVALUE> event) {
+ // Don't handle change events when setting initial value
+ if (valueInit) {
+ return;
+ }
+
if (binder != null) {
// Inform binder of changes; if setBean: writeIfValid
getBinder().handleFieldValueChange(this, event);
@@ -1180,8 +1183,7 @@ public class Binder<BEAN> implements Serializable {
@Override
public void read(BEAN bean) {
- field.setValue(converterValidatorChain.convertToPresentation(
- getter.apply(bean), createValueContext()));
+ getField().setValue(convertDataToFieldType(bean));
}
@Override
diff --git a/server/src/test/java/com/vaadin/data/BinderTest.java b/server/src/test/java/com/vaadin/data/BinderTest.java
index ef52ea8ef5..0163b65b51 100644
--- a/server/src/test/java/com/vaadin/data/BinderTest.java
+++ b/server/src/test/java/com/vaadin/data/BinderTest.java
@@ -11,6 +11,7 @@ import static org.junit.Assert.assertTrue;
import java.util.Locale;
import java.util.Objects;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;
@@ -1125,4 +1126,28 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> {
assertEquals(fiError,
ageField.getErrorMessage().getFormattedHtmlMessage());
}
+
+ @Test
+ public void valueChangeListenerOrder() {
+ AtomicBoolean beanSet = new AtomicBoolean();
+ nameField.addValueChangeListener(e -> {
+ if (!beanSet.get()) {
+ assertEquals("Value in bean updated earlier than expected",
+ e.getOldValue(), item.getFirstName());
+ }
+ });
+ binder.bind(nameField, Person::getFirstName, Person::setFirstName);
+ nameField.addValueChangeListener(e -> {
+ if (!beanSet.get()) {
+ assertEquals("Value in bean not updated when expected",
+ e.getValue(), item.getFirstName());
+ }
+ });
+
+ beanSet.set(true);
+ binder.setBean(item);
+ beanSet.set(false);
+
+ nameField.setValue("Foo");
+ }
}