2017-05-25 70 views
0

我正在使用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()的按钮,该支持项似乎没有得到更新d。所以没有更新的值被打印到控制台。

我在这里做错了什么?

回答

1

ViewModel可以像您可能知道的那样只是对JavaFX Properties进行双向绑定。您的域对象不包含JavaFX属性,因此您需要将其转换。但是,您正在使用的toProperty()函数仅对一个值进行操作,并将其转换为属性。该属性无法知道它是字段所有者,因此无法回写到域对象中。

幸运的是,你可以使用observable功能,使您的域对象的属性可写,以及:

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

由于observable功能上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改性剂也提防该插件的当前版本已在转换功能中的错误,将保留旧参数。 - 新版本即将发布)。

如果你不想因为各种原因这么做,我甚至可以像你一样支持这个很好的语法,所以从TornadoFX 1.7.6开始,你甚至可以在你的绑定语句中使用这个语法如果您不想更改您的数据类别:

val url = bind(MenuRoute::url)

相关问题