【问题标题】:TableView and Fragment to edit Details with tornadofxTableView 和 Fragment 使用 tornadofx 编辑详细信息
【发布时间】:2018-01-31 14:51:06
【问题描述】:

我将 kotlinx.serialization 用于我的模型。 我希望它们不依赖于 JavaFX,因此它们不公开属性。

给定一个模型,我想要一个 tableview 来快速表示实例列表,另外还有一个更详细的 Fragment 作为编辑器。

考虑以下模型:

@Serializable
data class Person(
        var name: String,
        var firstname: String,
        var complex: Stuff)

包含 tableview 的视图包含

private val personlist = mutableListOf<Person>().observable()

当按下 Enter 时,tableview 会为所选行打开一个 PersonEditor 的实例:

tableview(personlist) {
    column("name", Person::name)
    column("first name", Person::firstname)

    setOnKeyPressed { ev ->
        selectedItem?.apply {
            when (ev.code) {
                KeyCode.ENTER -> PersonEditor(this).openModal()
            }
        }
    }
}

我关注了this gitbook section(但不希望模型视图在选择表格视图中的另一行时反弹) 编辑器大概是这样的:

class PersonEditor(person: Person) : ItemFragment<Person>() {
    val model: Model = Model()

    override val root = form {
        fieldset("Personal information") {
            field("Name") {
                textfield(model.name)
            }
            field("Vorname") {
                textfield(model.firstname)
            }
        }
        fieldset("complex stuff") {
            //... more complex stuff here
        }
        fieldset {
            button("Save") {
                enableWhen(model.dirty)
                action { model.commit() }
            }
            button("Reset") { action { model.rollback() } }
        }
    }

    class Model : ItemViewModel<Person>() {
        val name = bind(Person::name)
        val firstname = bind(Person::firstname)
        //... complex stuff
    }

    init {
        itemProperty.value = mieter
        model.bindTo(this)
    }
}

当我在详细视图中保存编辑的值时,表格视图没有更新。 解决这个问题的最佳做法是什么?

我也不确定,如果我正在做的事情可以被认为是好的练习,所以我也很乐意为此提供一些建议。

【问题讨论】:

    标签: kotlin tornadofx


    【解决方案1】:

    JavaFX 应用程序中的最佳实践是使用可观察属性。不这样做是一场艰苦的战斗。您可以保留精益域对象,但添加具有可观察属性的 JavaFX/TornadoFX 特定版本。该对象可以知道如何将数据复制到/从您的“精简”域对象中。

    使用这种方法,尤其是与 ItemViewModel 包装器结合使用时,将确保您的数据始终保持更新。

    您发布的setOnKeyPressed代码可以更改为:

    setOnUserSelect {
        PersonEditor(it).openModal()
    }
    

    但请注意,您不应该直接实例化视图和片段,因为这样做会跳过 TornadoFX 生命周期中的某些步骤。相反,您应该将人员作为参数传递,或者创建一个新范围并将 PersonModel 注入该范围,然后在该范围中打开编辑器:

    setOnUserSelect {
        find<PersonEditor>(Scope(PersonEditor(it)))
    }
    

    【讨论】:

    • 为了用可观察的属性包装一个精简的Person-object,我可以/应该在所有地方简单地使用 ItemViewModel 吗?
    • 是的,你可以,但你可能必须重写 onCommit 并分配一个你在那里明确创建的新项目,因为你的精益对象是不可变的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多