【问题标题】:Get new value of TextField using data binding in JavaFX MVVM使用 JavaFX MVVM 中的数据绑定获取 TextField 的新值
【发布时间】:2021-04-03 16:14:52
【问题描述】:

我在 ViewModel 中将 TextField 绑定到 StringProperty,但此 StringProperty 仅获取旧值。

控制器:

@FXML
private TextField filterResultTextField;
---
this.filterResultTextField.textProperty().bindBidirectional(this.applicationViewModel.filterApplicationPropertyDataProperty());
---
this.filterResultTextField.textProperty().addListener((observable, oldValue, newValue) -> {
   this.applicationViewModel.filter();
});

视图模型:

private final StringProperty filterApplicationPropertyData = new SimpleStringProperty();
---
public StringProperty filterApplicationPropertyDataProperty() {
   return filterApplicationPropertyData;
}
---
public void filter() {
   var filterString = this.getFilterApplicationPropertyData() != null ? this.getFilterApplicationPropertyData().toLowerCase() : null;
  ...
}

使用上面的代码,private final StringProperty filterApplicationPropertyData = new SimpleStringProperty(); 将只有前一个/旧值,而不是当前值。我可以改为执行以下操作(它正在工作),但绑定实际上将变得毫无用处,我认为它不再是 MVVM:

// 控制器

this.filterResultTextField.textProperty().addListener((observable, oldValue, newValue) -> {
   this.applicationViewModel.filter(newValue);
});

// 视图模型

public void filter(String value ) {
   var filterString = value) != null ? value.toLowerCase() : null;
  ...
}

感谢您的帮助。谢谢你。

【问题讨论】:

  • 我怀疑这是一个惰性绑定的例子。如果从按钮触发 filter() 方法会发生什么?获取绑定属性的值实际上可能会触发正在更新的值。
  • 我尝试了你的建议。有用。但是,我不倾向于这个解决方案,因为我想实时进行过滤,因此,使用 addListener。一旦用户输入字符串,它就会执行过滤。
  • 这不是解决方案,只是对可能原因的验证。延迟绑定可能是一个真正的问题。但我认为绑定和添加侦听器的顺序并不重要。您确定解决了问题(如下所述)吗?还是只触发一次,因为添加监听器会同步属性?
  • 在 same 属性上有一个绑定和一个侦听器听起来很可疑.. 可能是设计错误
  • @tbeernot ok。那就验证了。至于解决方案,我想是的。我只是切换了绑定和侦听器的顺序。先绑定然后监听器。尝试切换第 44 行和第 45 行,它将不再起作用:gist.github.com/julianjupiter/97cdc2154f748ae4b82339bcdd8a2106

标签: java javafx mvvm data-binding textfield


【解决方案1】:

我发现了问题。在设置绑定之前首先创建了侦听器。在创建监听器之前应该先设置绑定。

【讨论】:

  • 实际上,不:如果这个 appears 作为解决方案,则设置存在严重错误 - 所有侦听器(并且绑定只是另一个侦听器)到同一个可观察对象都是平等,特别是他们不得依赖于通知的顺序。
  • @kleopatra 我切换了绑定和监听的顺序。首先绑定,然后是侦听器。你可以在这里验证它:gist.github.com/julianjupiter/97cdc2154f748ae4b82339bcdd8a2106。只需切换第 44 和 45 行。
  • 或者可能,我应该将侦听器移动到视图模型中的属性吗?
  • 这确实是代码味道;绑定和自定义侦听器都是侦听器,因此首先触发谁是一个问题。如果绑定是第一个,则在触发自定义侦听器之前对其进行更新。两个并行的侦听器不是一个好主意。要么只有监听器并做一个过滤器(textField.getValue()),要么在 filterProperty 上注册一个监听器以响应更改,要么从另一个事件(例如按钮)调用 filter() 方法。
  • 我会在VM中的filterProperty上放置一个监听器来调用filter方法,那么你就没有并行但链式的监听器。并删除控制器中的监听器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-28
  • 1970-01-01
  • 2023-04-03
  • 2017-08-20
相关资源
最近更新 更多