Views
8 months ago

tornadofx-guide

11. Editing Models and

11. Editing Models and Validation The person TableView now becomes a lot cleaner and easier to reason with. In a real application the list of persons would probably come from a controller or a remoting call though. The model is simply injected into the View , and we will do the same for the editor: class PersonEditor : View("Person Editor") { val model : PersonModel by inject() override val root = 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() { model.commit() println("Saving ${model.item.name} / ${model.item.title}") } The injected instance of the model will be the exact same one in both views. Again, in a real application the save call would probably be offloaded to a controller asynchronously. When to Use ViewModel vs ItemViewModel This chapter has progressed from the low-level implementation ViewModel into a streamlined ItemViewModel . You might wonder if there are any use cases for inheriting from ViewModel instead of ItemViewModel at all. The answer is that while you would typically extend ItemViewModel more than 90% of the time, there are some use cases where it does not make sense. Since ViewModels can be injected and used to keep navigational state and overall UI state, you might use it for situations where you do not have a single domain object 166

11. Editing Models and Validation - you could have multiple domain objects or just a collection of loose properties. In this use case the ItemViewModel does not make any sense, and you might implement the ViewModel directly. For common cases though, ItemViewModel is your best friend. There is one potential issue with this approach. If we want to display multiple "pairs" of lists and forms, perhaps in different windows, we need a way to separate and bind the model belonging to a spesific pair of list and form. There are many ways to deal with that, but one tool very well suited for this is the scopes. Check out the scope documentation for more information about this approach. Validation Almost every application needs to check that the input supplied by the user conforms to a set of rules or are otherwise acceptable. TornadoFX sports an extensible validation and decoration framework. We will first look at validation as a standalone feature before we integrate it with the ViewModel . Under the Hood The following explanation is a bit verbose and does not reflect the way you would write validation code in your application. This section will provide you with a solid understanding of how validation works and how the individual pieces fit together. Validator A Validator knows how to inspect user input of a specified type and will return a ValidationMessage with a ValidationSeverity describing how the input compares to the expected input for a specific control. If a Validator deems that there is nothing to report for an input value, it returns null . A text message can optionally accompany the ValidationMessage , and would normally be displayed by the Decorator configured in the ValidationContext . We will cover more on decorators later. The following severity levels are supported: Error - Input was not accepted Warning - Input is not ideal, but accepted Success - Input is accepted Info - Input is accepted 167

GUIDE
GUIDE
Guide
Guide
GUIDE
GUIDE
GUIDE
Guide
Guide
GUIDE
Guide
GUIDE
GUIDE
GUIDE
GUIDE