tornadofx
tornadofx copied to clipboard
workspace.dockInNewScope with custom scope?
From the documentation I know we can use a dockInNewScope call to prevent needing to set the workspace of the new scope. Can I use the same call when I want the new scope to be my own custom one? At the moment I am needing to do this:
val scope = PageScope()
scope.workspace = myWorkspace
val newPage = find<WikiPage>(scope)
myWorkspace.dock(newPage)
I would like to be able to replace the above lines with something such as:
dockInNewScope<WikiPage>(PageScope())
or (this would be even more useful for me):
dockInNewScope(WikiPage(), PageScope())
I can see the call accepts a ScopedInstance but I don't understand what this is, could someone help explain it for me please?
If you really have a use case for subclassing Scope, you can call the constructor that accepts a workspace:
class PageScope(workspace: Workspace) : Scope(workspace)
However, I suspect you have no need to actually subclass scope, so please revisit the reason you're creating a subclass.
If you really want to do this, this is the simplest way:
workspace.dock(find<WikiPage>(PageScope(workspace)))
Note that you must never instantiate UIComponents (Views/Fragments) manually, as they will miss out on important life cycle calls.
ScopedInstance is a superclass for "anything that can live in a scope", for example ViewModel, View, Controller etc.
However, I suspect you have no need to actually subclass scope, so please revisit the reason you're creating a subclass.
I'm using it based on the examples given in the scope part of the guide. I need multiple editors open at the same time so using scopes to group them apart made sense.
There's no need, just put a PersonModel in the scope, no need to subclass it. I can't actually think of any good use cases to subclass Scope in a normal app, so it might be best to remove that section from the guide. Sorry about the confusion :)
Fair enough, I'll look into refactoring those parts of my application.
I have run into another unrelated problem which I don't understand. So if you're still around I'd love a pointer here... I have a SimpleListProperty in my model:
val wikiNodeList = SimpleListProperty<TextNodeModel>(FXCollections.observableArrayList())
And I bind that in the view model:
val nodeList = bind(PageModel::wikiNodeList)
However when I try to call:
pageViewModel.nodeList.add(textNode.viewModel.item)
I get the following error:
Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: public fun EventTarget.add(node: Node): Unit defined in tornadofx
Any idea about this?
Edit:
pageViewModel.item.wikiNodeList.add(textNode.viewModel.item) works but my understanding is this is bad practice in View-viewmodel architecture
You're getting an extension function called add which is intented to be used to add UI elements to parent elements. Without seeing a complete example, I'm guessing, but I think you need to write nodeList.items.add().