mer*_*123 7 javafx kotlin tornadofx
我是javafx,kotlin和明显tornadofx的新手.
问题:
如何在每个实例上将参数传递给Fragment?
假设我有一个表视图布局作为我的片段.现在,此片段在多个位置使用,但具有不同的数据集.
例如.添加片段:
class SomeView : View() {
...
root += SomeViewFragment::class
}
class SomeAnotherView : View() {
...
root += SomeViewFragment::class
}
Run Code Online (Sandbox Code Playgroud)
声明片段:
class SomeViewFragment : Fragment() {
...
tableview(someDataSetFromRestApiCall) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
如何从SomeView和SomeAnotherView传递不同的someDataSetFromRestApiCall?
Edv*_*yse 14
让我们从最明确的方式将数据传递给Fragments开始.对于此TableView示例,您可以在Fragment中公开一个可观察列表,并将TableView绑定到此列表.然后,您可以从片段外部更新该列表,并将更改反映在片段中.在这个例子中,我创建了一个带有observable属性的简单数据对象SomeItem:
class SomeItem(name: String) {
val nameProperty = SimpleStringProperty(name)
var name by nameProperty
}
Run Code Online (Sandbox Code Playgroud)
现在我们可以SomeViewFragment使用绑定到TableView的item属性来定义:
class SomeViewFragment : Fragment() {
val items = FXCollections.observableArrayList<SomeItem>()
override val root = tableview(items) {
column("Name", SomeItem::nameProperty)
}
}
Run Code Online (Sandbox Code Playgroud)
如果您以后更新项目内容,更改将反映在表格中:
class SomeView : View() {
override val root = stackpane {
this += find<SomeViewFragment>().apply {
items.setAll(SomeItem("Item A"), SomeItem("Item B"))
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以对SomeOtherView其他数据执行相同操作:
class SomeOtherView : View() {
override val root = stackpane {
this += find<SomeViewFragment>().apply {
items.setAll(SomeItem("Item B"), SomeItem("Item C"))
}
}
}
Run Code Online (Sandbox Code Playgroud)
虽然这很容易理解且非常明确,但它会在您的组件之间创建非常强大的耦合.您可能需要考虑使用范围.我们现在有两个选择:
我们将首先使用选项1,通过注入数据模型.我们首先创建一个可以保存项目列表的数据模型:
class ItemsModel(val items: ObservableList<SomeItem>) : ViewModel()
Run Code Online (Sandbox Code Playgroud)
现在我们将这个ItemsModel注入到Fragment中并从该模型中提取项目:
class SomeViewFragment : Fragment() {
val model: ItemsModel by inject()
override val root = tableview(model.items) {
column("Name", SomeItem::nameProperty)
}
}
Run Code Online (Sandbox Code Playgroud)
最后,我们需要为每个视图中的片段定义一个单独的范围,并为该范围准备数据:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,setInScope上面使用的功能将在TornadoFX 1.5.9中提供.同时您可以使用:
FX.getComponents(fragmentScope).put(ItemsModel::class, model)
Run Code Online (Sandbox Code Playgroud)
另一种选择是将数据直接放入范围.让我们创建一个ItemsScope代替:
class ItemsScope(val items: ObservableList<SomeItem>) : Scope()
Run Code Online (Sandbox Code Playgroud)
现在我们的片段将获得一个实例,SomeItemScope因此我们将其转换并提取数据:
class SomeViewFragment : Fragment() {
override val scope = super.scope as ItemsScope
override val root = tableview(scope.items) {
column("Name", SomeItem::nameProperty)
}
}
Run Code Online (Sandbox Code Playgroud)
由于我们不需要模型,View现在需要做更少的工作:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:作为这个问题的结果,我们决定支持使用find和传递参数inject.从TornadoFX 1.5.9开始,您可以将项目列表作为参数发送,如下所示:
class SomeView : View() {
override val root = stackpane {
val params = "items" to listOf(SomeItem("Item A"), SomeItem("Item B")).observable()
this += find<SomeViewFragment>(params)
}
}
Run Code Online (Sandbox Code Playgroud)
现在SomeViewFragment可以获取这些参数并直接使用它们:
class SomeViewFragment : Fragment() {
val items: ObservableList<SomeItem> by param()
override val root = tableview(items) {
column("Name", SomeItem::nameProperty)
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这不涉及片段内的未经检查的演员.
您还可以通过EventBus传递参数和数据,这也将在即将发布的TornadoFX 1.5.9中传递.EventBus还支持范围,可以轻松定位您的事件.
您可以在指南中阅读有关Scopes,EventBus和ViewModel的更多信息:
| 归档时间: |
|
| 查看次数: |
2922 次 |
| 最近记录: |