绑定的属性不起作用
我正在使用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)