Kotlin 将视图绑定到正在更改的控制器属性

Kotlin 将视图绑定到正在更改的控制器属性,kotlin,tornadofx,Kotlin,Tornadofx,我在科特林和TornadoFX图书馆一起工作。假设您有一个工具栏,其中显示了对当前视图有用的工具。我们有一个主控制器,它有一个subcroller属性,它是工具栏旁边某个视图的控制器。因此,如果我们的分包器发生更改,视图应该更新。此外,如果子滚轴的任何属性(如selectedTool、tools)发生更改,则工具栏应相应更新。工具栏暂时不会更新 class ToolBar : View("Tool bar") { private val controller: MainControlle

我在科特林和TornadoFX图书馆一起工作。假设您有一个工具栏,其中显示了对当前视图有用的工具。我们有一个主控制器,它有一个subcroller属性,它是工具栏旁边某个视图的控制器。因此,如果我们的分包器发生更改,视图应该更新。此外,如果子滚轴的任何属性(如selectedTool、tools)发生更改,则工具栏应相应更新。工具栏暂时不会更新

class ToolBar : View("Tool bar") {
    private val controller: MainController by inject()
    override val root = vbox {
        tilepane {
            for (tool in controller.subController.tools) {
                button(tool.name, group).action {
                    controller.subController.changeTool(tool) // changes selected tool
                }
            }
        }
        this += controller.subController.selectedTool.options
    }
}
额外信息:Subcroller.tools是一个ArrayList,Subcroller.selectedTool是一个工具


现在我的问题是,在TornadoFX中,推荐的方法是什么?

您有几种选择。
Parent
支持一个名为
bindChildren
的函数,该函数接受一个可观察的项目列表,以及一个将这些项目中的每个项目转换为节点的函数。您可以使用此选项在工具栏中创建按钮:

tilepane { 
    bindChildren(controller.subController.tools) { tool ->
        Button(tool.name) ...
    }
}
如果需要更多控制,也可以手动执行此操作:

替利班{ controller.subcroller.tools.onChange{ 孩子们 //在这里创建新按钮,如示例中所示 } }

但是,您应该有一个注入到当前作用域中的ToolsModel,而不是注入控制器来访问这些工具。工具模型可以有一个工具和所选工具的列表,并且可以注入到所有需要它的视图和控制器中。您说selectedTool是一个工具,但您并没有显示工具是什么,但从代码来看,它看起来像Tool.options是一个节点子类(?)


您可以使用相同的技术添加/删除tool.options元素,甚至可以将其包装在stackpane或其他layoutcontainer中,以便在使用相同的技术进行更改时识别要删除的工具(或仅删除stackpane的所有子项)。

tool是一个自定义类,其中options属性是一个窗格。此外,如果重新分配了Subcroller属性,工具栏会更新吗?@Simonmarynisen我对TornadFX不太熟悉,但这是不可能的,因为即使它确实更新了子对象,但您只传递了
工具
列表,如果您更改了
subcroller
,则对旧
工具
列表的引用将不会更改。向subcroller添加可观察对象是否可以解决此问题?正如我所暗示的,解决方案是将任何更改放在ViewModel中,并根据需要进行更新。