2017-05-25 69 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)

相關問題