I am a newbie to javafx, kotlin and obviously tornadofx.
Issue:
How to pass parameters to Fragment on every instance?
Lets say I have a table view layout as my fragment. Now this fragment is used at multiple places but with different datasets.
eg. Adding a fragment in:
class SomeView : View() {
...
root += SomeViewFragment::class
}
class SomeAnotherView : View() {
...
root += SomeViewFragment::class
}
Declaring Fragment:
class SomeViewFragment : Fragment() {
...
tableview(someDataSetFromRestApiCall) {
...
}
}
How can I pass different someDataSetFromRestApiCall from SomeView and SomeAnotherView ?
Let's start with the most explicit way to pass data to Fragments. For this TableView example you could expose an observable list inside the Fragment and tie your TableView to this list. Then you can update that list from outside the Fragment and have your changes reflected in the fragment. For the example I created a simple data object with an observable property called
SomeItem
:Now we can define the
SomeViewFragment
with an item property bound to the TableView:If you later update the items content, the changes will be reflected in the table:
You can then do the same for
SomeOtherView
but with other data:While this is easy to understand and very explicit, it creates a pretty strong coupling between your components. You might want to consider using scopes for this instead. We now have two options:
Use injection inside the scope
We will go with option 1 first, by injecting the data model. We first create a data model that can hold our items list:
Now we inject this ItemsModel into our Fragment and extract the items from that model:
Lastly, we need to define a separate scope for the fragments in each view and prepare the data for that scope:
Please not that the
setInScope
function used above will be available in TornadoFX 1.5.9. In the mean time you can use:Let the scope contain the data
Another option is to put data directly into the scope. Let's create an
ItemsScope
instead:Now our fragment will expect to get an instance of
SomeItemScope
so we cast it and extract the data:The View needs to do less work now since we don't need the model:
Passing parameters
EDIT: As a result of this question, we decided to include support for passing parameters with
find
andinject
. From TornadoFX 1.5.9 you can therefore send the items list as a parameter like this:The
SomeViewFragment
can now pick up these parameters and use them directly:Please not that this involves an unchecked cast inside the Fragment.
Other options
You could also pass parameters and data over the EventBus, which will also be in the soon to be released TornadoFX 1.5.9. The EventBus also supports scopes which makes it easy to target your events.
Further reading
You can read more about Scopes, EventBus and ViewModel in the guide:
Scopes
EventBus
ViewModel and Validation