Here it is said that we have 2 options to implement MVVM with JavaFX - it depends whether we want to use JavaFX-Properties in our model or not.
As I understand if my model doesn't have javafx properties then I add fx properties to ViewModel. However, I can't understand what I should do if my model has fx properties. What should I do this case? Something like this:
class ViewModel {
private ObjectProperty<Person> personProperty = new SimpleObjectProperty<>();
...
personProperty.set(person);
}
or I should duplicate all the properties of the Person in ViewModel and bind every ViewModel property to Person properties, to get View -><- ViewModel -><- Model
? Could anyone explain what to do this case?
There are 2 solutions with their own advantages and drawbacks.
If you want to stay 100% true to the MVVM pattern your View may not know any model classes. Therefore it's not allowed to give a personProperty from the ViewModel to the View. Instead you have to duplicate the fields of the model class as properties in the ViewModel, for example "firstnameProperty". These properties can now be used (typically by data-binding) in the View. The View doesn't know anything about a model class 'Person'. Instead it only knows the properties that the ViewModel provides.
However, now you have to keep these properties in sync with the actual model instance in the ViewModel. To make this easier some time ago I've created the ModelWrapper util as part of the mvvmFX framework. In addition to classic Java POJOs it also supports classes with JavaFX Properties. You can see the a usage example in the tests of the class here. It uses a Model class with JavaFX properties (here).
This is the recommended approach. However, depending on the complexity of your model classes this can get tricky. For complex models with a deep structure you might need to write your own logic to keep the properties in sync with your model classes. This is one of the trickiest parts of MVVM pattern.
The other approach is to relax the limitations of the MVVM pattern and to pass the Model instance to the View. This can be a solution if your Model class has lots of fields and it would be to much code to duplicate each field in the ViewModel. However, this way you are introducing a dependency from your View to your Model which is agains the idea of MVVM.