【发布时间】: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