On Wed, Nov 10, 2021 at 12:12 PM John Hendrikx <hj...@xs4all.nl> 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.
I don't think it would have to apply for unidirectional bindings, as it is exceedingly rare that you would want to unidirectionally bind the value of a model-layer property to a view-layer property, but not vice versa. After all, you'd probably want your input controls to reflect the initial state of the model. In any way, it sure is a kind-of high level concern, but in my experience, it's a very common problem at least for some software architectures without a great solution. > 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). Well, that requires you to pull in another third-party dependency, and even then you would need to roll your own bidirectional binding implementation. It might work for the focus-lost behavior, but not for the ActionEvent behavior. Of course, you can do all of that, but this doesn't seem to me like a great value proposition for solving a very common problem. > 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. There are no additional edge cases compared to vanilla bidirectional bindings. Bidirectional bindings with an UpdateSourceTrigger will have exactly the same concurrency behavior as vanilla bidirectional bindings (i.e. they don't support concurrent modification at all). I'm not sure how the FX thread relates to this, as bidirectional bindings don't know about threads in any case. Note that UpdateSourceTrigger only applies to the target->source direction. The source->target direction, which is the scenario you describe when the model is updated while the view is being edited, is exactly the same as it is for vanilla bidirectional bindings.