Skip to content

Commit 76b862a

Browse files
authored
fix: run setBean validation for changed bindings only (#18735) (#18760)
1 parent 4cb93d2 commit 76b862a

File tree

1 file changed

+33
-28
lines changed
  • flow-data/src/main/java/com/vaadin/flow/data/binder

1 file changed

+33
-28
lines changed

flow-data/src/main/java/com/vaadin/flow/data/binder/Binder.java

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1920,10 +1920,24 @@ public static <BEAN> Binder<BEAN> withPropertySet(
19201920
*/
19211921
protected void handleFieldValueChange(Binding<BEAN, ?> binding) {
19221922
changedBindings.add(binding);
1923-
if (getBean() != null) {
1924-
doWriteIfValid(getBean(), changedBindings);
1923+
1924+
if (getBean() == null) {
1925+
binding.validate();
19251926
} else {
1926-
validate(binding);
1927+
BinderValidationStatus<BEAN> status = validateBindingsAndBean();
1928+
if (status.isOk()) {
1929+
doWriteIfValid(getBean(), changedBindings);
1930+
} else {
1931+
// Fire status change for changed bindings only
1932+
getValidationStatusHandler()
1933+
.statusChange(new BinderValidationStatus<>(this,
1934+
status.getFieldValidationStatuses().stream()
1935+
.filter(s -> changedBindings
1936+
.contains(s.getBinding()))
1937+
.collect(Collectors.toList()),
1938+
status.getBeanValidationErrors()));
1939+
fireStatusChangeEvent(status.hasErrors());
1940+
}
19271941
}
19281942
}
19291943

@@ -2512,9 +2526,10 @@ private BinderValidationStatus<BEAN> doWriteIfValid(BEAN bean,
25122526
bindings);
25132527

25142528
// First run fields level validation, if no validation errors then
2515-
// update bean. Note that this will validate all bindings.
2516-
List<BindingValidationStatus<?>> bindingResults = getBindings().stream()
2517-
.map(b -> b.validate(false)).collect(Collectors.toList());
2529+
// update bean.
2530+
List<BindingValidationStatus<?>> bindingResults = currentBindings
2531+
.stream().map(b -> b.validate(false))
2532+
.collect(Collectors.toList());
25182533

25192534
if (bindingResults.stream()
25202535
.noneMatch(BindingValidationStatus::isError)) {
@@ -2781,35 +2796,25 @@ protected BinderValidationStatus<BEAN> validate(boolean fireEvent) {
27812796
}
27822797

27832798
/**
2784-
* Validates the target binding. Also runs validation for all other
2785-
* bindings, and if possible, bean-level validations as well.
2799+
* Runs validation for all bindings to determine binder's validity state. If
2800+
* a bean has been set and all bindings pass validation, bean-level
2801+
* validations are run as well.
27862802
*
2787-
* {@link BinderValidationStatusHandler} is called with only the status of
2788-
* the target binding.
2789-
*
2790-
* {@link StatusChangeEvent} is fired with current binder validation status
2791-
*
2792-
* @param targetBinding
2793-
* target binding for validation
2803+
* @return BinderValidationStatus for the validation run
27942804
*/
2795-
private void validate(Binding<BEAN, ?> targetBinding) {
2796-
List<BindingValidationStatus<?>> bindingValidationStatuses = validateBindings();
2805+
private BinderValidationStatus<BEAN> validateBindingsAndBean() {
2806+
List<BindingValidationStatus<?>> bindingStatuses = validateBindings();
2807+
boolean bindingsInError = bindingStatuses.stream()
2808+
.anyMatch(BindingValidationStatus::isError);
27972809

27982810
List<ValidationResult> beanStatuses = new ArrayList<>();
2799-
if (getBean() != null) {
2811+
// Only execute bean-level validation when binding validators pass
2812+
if (!bindingsInError) {
28002813
beanStatuses.addAll(validateBean(getBean()));
28012814
}
2802-
BindingValidationStatus<?> status = bindingValidationStatuses.stream()
2803-
.filter(s -> targetBinding.equals(s.getBinding())).findFirst()
2804-
.orElse(null);
2805-
2806-
getValidationStatusHandler().statusChange(new BinderValidationStatus<>(
2807-
this, Collections.singletonList(status),
2808-
Collections.emptyList()));
28092815

2810-
fireStatusChangeEvent(bindingValidationStatuses.stream()
2811-
.anyMatch(BindingValidationStatus::isError)
2812-
|| beanStatuses.stream().anyMatch(ValidationResult::isError));
2816+
return new BinderValidationStatus<>(this, bindingStatuses,
2817+
beanStatuses);
28132818
}
28142819

28152820
/**

0 commit comments

Comments
 (0)