在JavaFXMVVM中使用数据绑定获取TextField的新值

在JavaFXMVVM中使用数据绑定获取TextField的新值,java,javafx,mvvm,data-binding,textfield,Java,Javafx,Mvvm,Data Binding,Textfield,我已将TextField绑定到ViewModel中的StringProperty,但此StringProperty仅获取旧值 控制器: @FXML private TextField filterResultTextField; --- this.filterResultTextField.textProperty().bindBidirectional(this.applicationViewModel.filterApplicationPropertyDataProperty()); ---

我已将TextField绑定到ViewModel中的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;
  ...
}
使用上述代码,
私有最终StringProperty过滤器ApplicationPropertyData=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。一旦用户输入字符串,它就会执行过滤。这不是一个解决方案,只是一个可能原因的验证。延迟绑定可能是一个真正的问题。但我认为绑定和添加侦听器的顺序并不重要。您确定解决了问题(如您在下面提到的)?或者它只触发一次,因为添加侦听器将同步属性?在同一属性上具有绑定和侦听器听起来很可疑。。设计错误,probably@tbeernot好啊那就验证了。至于解决办法,我想是的。我只是切换了绑定和侦听器的顺序。首先绑定,然后是侦听器。尝试切换第44行和第45行,它将不再工作:事实上,否:如果这是一个解决方案,那么设置中存在严重错误-到同一个可观察对象的所有侦听器(绑定只是另一个侦听器)都是相等的,特别是它们不能依赖于通知的顺序。@kleopatra I切换绑定和侦听器的顺序。首先绑定,然后是侦听器。您可以在此处验证它:。只需切换第44行和第45行。或者,我是否应该将侦听器移动到viewmodel中的属性?这确实是一种代码气味;绑定和自定义侦听器都是侦听器,因此首先触发的是谁。如果绑定是第一个,则会在触发自定义侦听器之前进行更新。两个并行的侦听器不是一个好主意。要么只使用侦听器并执行筛选器(textField.getValue()),要么在filterProperty上注册侦听器以对更改作出反应,要么从另一个事件(例如按钮)调用filter()方法。我会在VM的filterProperty上放置一个侦听器以调用筛选器方法,这样您就没有并行但链接的侦听器。当然,删除控制器中的侦听器。