Bidirectional binding enhancement
Kevin Rushforth
kevin.rushforth at oracle.com
Sat Nov 13 00:31:43 UTC 2021
In addition to the points John raises, I also agree with the comment Tom
added to the Draft PR: I don't think the object bindings in javafx.base
should have UI concepts like Action or Focus, even if you abstract them
a bit.
-- Kevin
On 11/10/2021 3:10 AM, John Hendrikx wrote:
> Although I think you have a valid use case, I don't think JavaFX
> should facilitate this exact scenario; it is a high level concern that
> you want to solve in a very low level mechanism. A similar scenario
> also applies to uni-directional bindings, so I think it would have to
> apply there as well.
>
> It also really depends on how you are doing the communication between
> view and model. Some system use models that are always valid, some
> systems use a view-model that contains a direct copy of what is in the
> UI controls. Some views allow users to type anything and do validation
> on submission or focus loss; some do per character validation and mark
> bad input; some will not even allow you to type bad input.
>
> For a scenario like you describe, which seems to be about delayed
> updates of bindings, I think you really want to use something like
> ReactFX's EventStreams. These offer far more features, including
> timeouts, removal of duplicates, combining of values, conditional
> suspending, etc. It might work like this for example:
>
> EventStream.of(textInput.textProperty())
> .conditionOn(textInput.focusedProperty().not())
> .feedTo(model::valueProperty);
>
> Or with Val:
>
> Val.of(textInput.textProperty())
> .conditionOn(textInput.focusedProperty().not())
> .subcribe(v -> updateModel(v));
>
> (Note: conditionOn is part of the fluent bindings proposal that Nir
> Lisker and me have been working on).
>
> Now, this isn't bidirectional, but I don't see how that will work in
> any case as there are some edge cases. For example, how would you
> handle a model update when the view is currently being edited?
> Delaying updates runs into issues where both may have changed, whereas
> currently bindings are resolved immediately on the FX thread.
>
> --John
>
> On 10/11/2021 06:45, Michael Strauß wrote:
>> JavaFX developers routinely use programming patterns like MVC, MVP, or
>> MVVM to separate views from their associated business logic. Bindings
>> can be used to connect the values of UI controls (like Label or
>> TextField) to properties on a business logic class.
>>
>> A typical (simplified) scenario may look like this:
>>
>> var valueField = new TextField();
>> valueField.textProperty().bindBidirectional(businessLogic.valueProperty());
>>
>>
>> The business logic class may perform data validation or other actions
>> on the value that was entered in the TextField. However, in many
>> cases, it is neither necessary nor desirable for the binding to update
>> the business-layer property on every single change (i.e. every single
>> character that was typed by a user). For example, if a business rule
>> verifies that the data entered by a user is formatted in a specific
>> way, it's usually not a great experience to yield a validation error
>> before the user has finished typing. Instead, it's often better to
>> wait until the user has significantly interacted with a UI control
>> before running business logic.
>>
>> For this reason, I propose to add a new type of binding to the
>> javafx.beans.binding.Bindings class:
>>
>> void bindBidirectional(Property<T> target, Property<T> source,
>> UpdateSourceTrigger trigger)
>>
>> UpdateSourceTrigger is an enumeration that allows developers to
>> specify the condition on which changes of the target property will
>> update the source property. Its values are:
>>
>> DEFAULT: Updates the source property on every change (this is the
>> default behavior of bidirectional bindings).
>> FOCUS: Updates the source property when the UI control loses input
>> focus.
>> ACTION: Updates the source property when the UI control loses input
>> focus or when it receives an ActionEvent (in the case of TextField,
>> this corresponds to the ENTER key).
>>
>> Note that this setting only applies to changes of the target property.
>> When the source property is changed instead, the target property is
>> always immediately updated.
>>
>> Any feedback on this proposal is appreciated.
>>
More information about the openjfx-dev
mailing list