Search code examples
kotlintornadofx

TornadoFX: How to preserve `ItemViewModel`'s property?


Good day. I am trying to preserve a property of ItemViewModel via config helper. I am able to successfully save the property (conf directory with appropriate .properties file is generated), however upon next start, the property does not restore its value, just remains null. Here's a sample code to demonstrate my issue:

import javafx.beans.property.SimpleStringProperty
import tornadofx.*

data class Foo(val doNotPreserveMe: String, val preserveMe: String)

class FooModel : ItemViewModel<Foo>() {
    val doNotPreserveMe = bind { item?.doNotPreserveMe?.toProperty() }
    val preserveMe = bind { SimpleStringProperty(item?.preserveMe, "pm", config.string("pm")) }
}

class FooApp : App(FooView::class)

class FooView : View() {
    private val model = FooModel()

    override val root = form {
        fieldset {
            field("Do not preserve me") { textfield(model.doNotPreserveMe).required() }
            field("Preserve me") { textfield(model.preserveMe).required() }
            button("Do something") {
                enableWhen(model.valid)
                action {
                    model.commit {
                        // ...
                        with(config) {
                            set("pm" to model.preserveMe.value)
                            save()
                        }
                    }
                }
            }
        }
    }
}

Any ideas on why the model is not restoring the value?


Solution

  • Each Component has it's own config store, which is backed by a separate file. Either make sure to use the same config file, or the app global config file.

    You can refer to other component's config store, so one solution would be to let the View access the ViewModel's config store like this:

    button("Do something") {
        enableWhen(model.valid)
        action {
            model.commit {
                // ...
                with(model.config) {
                    set("pm" to model.preserveMe.value)
                    save()
                }
            }
        }
    }
    

    However, there is a much simpler and more contained solution, which is simply to handle save in the FooModel's onCommit callback

    override fun onCommit() {
        with(config) {
            set("pm" to preserveMe.value)
            save()
        }
    }
    

    In this case you'd simply call model.commit() in the button callback.

    You can also use a common, or even global config object. Either use a Controller's config store, or the global store. To use the global config object, just refer to app.config in both the model and the view.