Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javafx Tornadofx-如何将参数传递给每个实例上的片段_Javafx_Kotlin_Tornadofx - Fatal编程技术网

Javafx Tornadofx-如何将参数传递给每个实例上的片段

Javafx Tornadofx-如何将参数传递给每个实例上的片段,javafx,kotlin,tornadofx,Javafx,Kotlin,Tornadofx,我是javafx、kotlin和tornadofx的新手。 问题: 如何将参数传递给每个实例上的片段 假设我有一个表视图布局作为我的片段。现在,这个片段在多个地方使用,但数据集不同 例如。 在中添加一个片段: class SomeView : View() { ... root += SomeViewFragment::class } class SomeAnotherView : View() { ... root += SomeViewFragment::class } 声明片段:

我是javafx、kotlin和tornadofx的新手。
问题:
如何将参数传递给每个实例上的片段

假设我有一个表视图布局作为我的片段。现在,这个片段在多个地方使用,但数据集不同

例如。 在中添加一个片段:

class SomeView : View() {
... 
root += SomeViewFragment::class
}

class SomeAnotherView : View() {
... 
root += SomeViewFragment::class
}
声明片段:

class SomeViewFragment : Fragment() {
...
    tableview(someDataSetFromRestApiCall) {
    ...
    }
}

如何从restapicall到SomeView和SomeAnotherView传递不同的somedataset?

让我们从向片段传递数据的最显式方式开始。对于这个TableView示例,您可以在片段中公开一个可观察列表,并将您的TableView绑定到此列表。然后,您可以从片段外部更新该列表,并在片段中反映您的更改。例如,我创建了一个简单的数据对象,它具有一个名为
SomeItem
的可观察属性:

class SomeItem(name: String) {
    val nameProperty = SimpleStringProperty(name)
    var name by nameProperty
}
现在,我们可以使用绑定到TableView的item属性定义
SomeViewFragment

class SomeViewFragment : Fragment() {
    val items = FXCollections.observableArrayList<SomeItem>()

    override val root = tableview(items) {
        column("Name", SomeItem::nameProperty)
    }
}
虽然这很容易理解并且非常明确,但它在组件之间创建了非常强的耦合。您可能需要考虑使用作用域来代替此。我们现在有两个选择:

  • 在范围内使用注射
  • 让作用域包含数据
  • 在范围内使用注射 我们将首先使用选项1,通过注入数据模型。我们首先创建一个可以保存项目列表的数据模型:

    class ItemsModel(val items: ObservableList<SomeItem>) : ViewModel()
    
    最后,我们需要为每个视图中的片段定义一个单独的范围,并为该范围准备数据:

    class SomeView : View() {
    
        override val root = stackpane {
            // Create the model and fill it with data
            val model= ItemsModel(listOf(SomeItem("Item A"), SomeItem("Item B")).observable())
    
            // Define a new scope and put the model into the scope
            val fragmentScope = Scope()
            setInScope(model, fragmentScope)
    
            // Add the fragment for our created scope
            this += find<SomeViewFragment>(fragmentScope)
        }
    }
    
    让作用域包含数据 另一种选择是将数据直接放入范围。让我们创建一个
    itemscope

    class ItemsScope(val items: ObservableList<SomeItem>) : Scope()
    
    视图现在需要做的工作更少,因为我们不需要模型:

    class SomeView : View() {
    
        override val root = stackpane {
            // Create the scope and fill it with data
            val itemsScope= ItemsScope(listOf(SomeItem("Item A"), SomeItem("Item B")).observable())
    
            // Add the fragment for our created scope
            this += find<SomeViewFragment>(itemsScope)
        }
    }
    
    SomeViewFragment
    现在可以拾取这些参数并直接使用它们:

    class SomeViewFragment : Fragment() {
        val items: ObservableList<SomeItem> by param()
    
        override val root = tableview(items) {
            column("Name", SomeItem::nameProperty)
        }
    }
    
    class-SomeViewFragment:Fragment(){
    val项:按参数()列出的ObservableList
    覆盖val root=tableview(项){
    列(“名称”,SomeItem::nameProperty)
    }
    }
    
    请注意,这不涉及片段内部未经检查的强制转换

    其他选择 您还可以通过EventBus传递参数和数据,EventBus也将在即将发布的TornadoFX 1.5.9中。EventBus还支持作用域,使您可以轻松地确定事件的目标

    进一步阅读 您可以在指南中阅读有关作用域、EventBus和ViewModel的更多信息:


    由于这个问题,我们现在讨论是否应该在组件中添加对参数的支持,有点像HTTP请求参数,使在视图、片段甚至控制器之间传递消息更加方便:)我们刚刚添加了params选项,我更新了上面的答案。哇!!谢谢你这么好的解释。我刚刚实现了“在范围内使用注入”部分,它工作起来很有魅力。我赞扬你们做了如此出色的工作,提供了即时支持和帮助。谢谢Edvin和团队:)@mercy123如果您还有任何问题或想法,请随时加入我们的#tornadofx Slack频道。我们欢迎因人们的需要而产生的新特性。
    FX.getComponents(fragmentScope).put(ItemsModel::class, model)
    
    class ItemsScope(val items: ObservableList<SomeItem>) : Scope()
    
    class SomeViewFragment : Fragment() {
        override val scope = super.scope as ItemsScope
    
        override val root = tableview(scope.items) {
            column("Name", SomeItem::nameProperty)
        }
    }
    
    class SomeView : View() {
    
        override val root = stackpane {
            // Create the scope and fill it with data
            val itemsScope= ItemsScope(listOf(SomeItem("Item A"), SomeItem("Item B")).observable())
    
            // Add the fragment for our created scope
            this += find<SomeViewFragment>(itemsScope)
        }
    }
    
    class SomeView : View() {
        override val root = stackpane {
            val params = "items" to listOf(SomeItem("Item A"), SomeItem("Item B")).observable()
            this += find<SomeViewFragment>(params)
        }
    }
    
    class SomeViewFragment : Fragment() {
        val items: ObservableList<SomeItem> by param()
    
        override val root = tableview(items) {
            column("Name", SomeItem::nameProperty)
        }
    }