diff options
author | Teemu Suo-Anttila <tsuoanttila@users.noreply.github.com> | 2018-03-24 15:02:39 +0200 |
---|---|---|
committer | Ilia Motornyi <elmot@vaadin.com> | 2018-03-24 15:02:39 +0200 |
commit | 00c3f2c37c104498e23bd8f25dfd5ab8ce65294b (patch) | |
tree | 86be279141ce928738b6b1ce4e77b109ee06a5c0 /server | |
parent | 3cd5e1a1dab61b8a6b328c0839211b6862d15521 (diff) | |
download | vaadin-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.java | 18 | ||||
-rw-r--r-- | server/src/test/java/com/vaadin/data/BinderTest.java | 25 |
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"); + } } |