如果不公开 JavaFX 属性的支持对象发生更改,则 TornadoFX ItemViewModel 会更新

TornadoFX ItemViewModel updating if backing object that do not expose JavaFX properties is changed

我有以下代码

class MainView : View("Example") {
    val model: UserModel = UserModel()

    init {
        model.item = User(status = true)
    }

    override val root = vbox {
        useMaxWidth = true
        label(model.status)
        button("Get new status") {
            action {
                model.item.updateStatus()
                println("Status in model: ${model.status.value}")
                println("Status in backing object: ${model.item.status}")
            }
        }
    }
}

class User(var status: Boolean, val api: Api = Api()) {

    fun updateStatus() {
        status = api.getStatus()
    }
}


class UserModel : ItemViewModel<User>() {
    val status = bind(User::status)
}


class Api {
    fun getStatus(): Boolean {
        val list = listOf(true, false)
        return list[(Math.random() * list.size).toInt()]
    }
}

单击按钮后,model.itemProperty 会发生变化,但 model.status 不会。调用 model.rollback() 可以解决问题,但我认为这不是在支持 属性 更改后更新 ItemViewModel 的正确方法。有没有 TornadoFX 的方法来更新 UserModel(以及相应的结果视图)而不将新的 User 对象分配给 model.item

当您的支持对象不可观察时,调用 rollback() 是正确的做法。语义完全适合您的用例,因为回滚确保您的 ViewModel 与已分配的支持对象中的值相匹配。

在你的情况下,你知道发生了什么变化,所以如果你想保持现有值不变,只更新状态,你最好务实一点:

model.status.value = model.item.status

就我个人而言,我总是尽可能使用可观察值,它们不会为新语法添加太多样板,而且它们使您能够以更具声明性的方式编写代码。为了完整起见,这就是您将 status 声明为 User 中的可观察 属性 的方式:

val statusProperty = SimpleBooleanProperty()
var status by statusProperty