Closed dragonic09 closed 5 years ago
It depends on whether you were using an ItemViewModel or a ViewModel - for example:
class PersonModel(var person: Person? = null) : ViewModel() {
val name = bind(true, defaultValue = "Yoyo") { person?.nameProperty() ?: SimpleStringProperty() as Property<String> }
}
// JavaFX Property
open class PersonModel(person: Person? = null) : ItemViewModel<Person>(person) {
val name = bind { item?.nameProperty() }
val age = bind { item?.ageProperty() }
val phone = bind { item?.phoneProperty() }
val email = bind { item?.emailProperty() }
}
ItemViewModel is a subclass of ViewModel, and possesses the property item
in its class (which you can see if you click Cmd + click the ItemViewModel
in the IDE to dig into the code). Hope this helps!
Can you post the surrounding/complete code so I know exactly where you're taking this from? On a general note, there is almost never a need to implement rebindOnChange
, this is included mostly to explain what happens behind the scenes.
https://edvin.gitbooks.io/tornadofx-guide/content/part1/11.%20Editing%20Models%20and%20Validation.html At "Introducing ViewModel section."
class PersonEditor : View("Person Editor") {
override val root = BorderPane()
val persons = listOf(Person("John", "Manager"), Person("Jay", "Worker bee")).observable()
val model = PersonModel(Person())
init {
with(root) {
center {
tableview(persons) {
column("Name", Person::nameProperty)
column("Title", Person::titleProperty)
// Update the person inside the view model on selection change
model.rebindOnChange(this) { selectedPerson ->
person = selectedPerson ?: Person()
}
}
}
right {
form {
fieldset("Edit person") {
field("Name") {
textfield(model.name)
}
field("Title") {
textfield(model.title)
}
button("Save") {
enableWhen(model.dirty)
action {
save()
}
}
button("Reset").action {
model.rollback()
}
}
}
}
}
}
private fun save() {
// Flush changes from the text fields into the model
model.commit()
// The edited person is contained in the model
val person = model.person
// A real application would persist the person here
println("Saving ${person.name} / ${person.title}")
}
}
class PersonModel(person: Person) : ItemViewModel<Person>(person) {
val name = bind(Person::nameProperty)
val title = bind(Person::titleProperty)
}
Ah, I see. I've updated the code and also added a warning stating that this is not the way to do it, it just explains what's going on inside the view model. You should probably never write your code this way. I've also included:
"The above example is included to clarify how the rebindOnChange()
function works under the hood. For real use cases involving a TableView
, you should opt for the bindSelected(model)
function that is available when you combine TableView
and ItemViewModel
."
Thank you! I was just trying to see how the code work, so I had been playing with it a bit. :+1:
Great :) Thanks for reporting. Some areas of the guide should probably be rewritten because we have better ways of doing stuff now, and some of the explanations of old concepts are just confusing to new users. Please report if you find more inaccuracies :)
Hi,
After I copied the code from the Introducing ViewModel section into Intellij IDE, I found that there are Unresolved reference errors in
model.rebindOnchange
and in thesave
function, which occur fromperson
.then I change it to
the errors are vanished, but I'm not sure if this is the right way to fix because I'm new to Tornadofx and Kotlin.