绑定的属性不起作用

我正在使用TornadoFX 1.7.5,我似乎无法获得绑定属性的工作。 我有下面的ItemViewModels

class DynamicMenuViewModel : ItemViewModel<DynamicMenu>(DynamicMenu()) { val title = bind { item?.title?.toProperty() } val isBold = bind { item?.isBold?.toProperty() } val routes = bind { item?.routes?.toProperty() } } data class DynamicMenu(var title: String = "", var isBold: Boolean = false, var routes: MutableList<MenuRouteViewModel> = mutableListOf()) class MenuRouteViewModel : ItemViewModel<MenuRoute>(MenuRoute()) { val url = bind { item?.url?.toProperty() } val title = bind { item?.title?.toProperty() } val isBold = bind { item?.isBold?.toProperty() } val showNew = bind { item?.showNew?.toProperty() } } data class MenuRoute(var url: String = "", var title: String = "", var showNew: Boolean = false, var isBold: Boolean = false) 

这样绑定:

 //routesController.dynamicMenu is an instance of DynamicMenuViewModel() textfield(property = routesController.dynamicMenu.title) { prefWidth = formWidth * .5 gridpaneConstraints { columnRowIndex(0, 1) marginLeft = 10.0 columnSpan = 2 marginBottom = 20.0 } } checkbox(property = routesController.dynamicMenu.isBold){ gridpaneConstraints { columnRowIndex(2, 1) marginLeft = 15.0 marginBottom = 20.0 } } 

然后,当我点击一个按钮时,以下功能提交模型并将它们打印到屏幕上:

  fun onClick(){ commitModel() println(dynamicMenu.item.toString()) dynamicMenu.item.routes.forEach { println(it.item.toString()) } } fun commitModel(){ dynamicMenu.item.routes.forEach { it.commit() } dynamicMenu.commit() } 

问题是,当我运行程序并编辑文本框和复选框,然后单击运行onClick()的按钮,支持项目似乎并没有得到更新。 所以没有更新的值被打印到控制台。

我在这里做错了什么?

您可能只知道ViewModel只能双向绑定JavaFX属性。 你的域对象不包含JavaFX属性,所以你需要转换它们。 但是,您使用的toProperty()函数仅对一个值进行操作,并将其转换为Property。 这个属性没有办法知道它的字段所有者,因此不能写回域对象。

幸运的是,您可以使用observable函数来使您的域对象属性可写:

val url = bind { item?.observable(MenuRoute::url) }

由于observable函数对MenuRoute对象的特定实例进行MenuRoute ,因此当您commit()模型时,它现在具有足够的信息来回写该实例。

如果您考虑更改域对象中的属性以使其可观察,则可以这样写:

val url = bind(MenuRoute::url)

您可以使用TornadoFX IDEA插件检查“将所有属性转换为TornadoFX属性”来自动重写您的属性。 这会将您的MenuRoute对象转换为:

 class MenuRoute { val isBoldProperty = SimpleBooleanProperty(false) var isBold by isBoldProperty val showNewProperty = SimpleBooleanProperty(false) var showNew by showNewProperty val urlProperty = SimpleStringProperty("") var url by urlProperty val titleProperty = SimpleStringProperty("") var title by titleProperty } 

(你必须手动删除你的类的data修饰符,同时要注意,当前版本的插件在转换函数中有一个bug,会遗留旧的参数 – 一个新的版本将很快发布)。

如果因为各种原因,你不想这样做,我只是能够支持这样的语法,即使是像你这样可变的变量,所以从TornadoFX 1.7.6你可以在绑定语句中使用这个语法,你想改变你的数据类:

val url = bind(MenuRoute::url)