The 6.0 release of ZK introduced the MVVM pattern and they have been fairly well documented in their website. Using the new pattern with zkgrails is another story. Its major attraction to me is that it is farily easy to unit test a ViewModel, compared to testing a Composer(has anyone been able to do this?). I decided delved into it today and figured that the best way to do it was to start a brand new project and try different things. In the end, I did the hard way first and later found out a rather easier way. So, without further ado, here we go.
The source code for the sample app can be found on github. I won't explain how to install grails and the zkgrails plugin. The domain class Person is shown here: First I needed a form to create persons, so I created the corresponding zul: create-zul com.example.create This creates a zul under grails-app/zul The corresponding view model was also created: create-viewmodel com.example.Person A PersonViewModel.groovy was added to grails-app/viewmodels/com/example/ ZK has some issues keeping hibernate sessions, so as a work around, zkgrails has facades. We will use a PersonFacade to interact with GORM: The test for the PersonViewModel: And finally our PersonViewModel: A couple things to point out before we continue.- @WireVariable is needed to wire a spring bean. All facades created by zkgrails are spring beans, so we need this annotation to wire it.
- @NotifyChange is used to notify the corresponding variables of any changes.
- @Command is the equivalent of an onCLick_ method. This can be used to bind an event in the UI to a method in the ViewModel.
- A custom validtor to ensure that the first name is added.
- @id('vm') : this assigns viewmodel to a variable(vm) allowing us to access it throughout our view.
- @init('com.example.PersonViewModel') : assigns an instance of this class to vm.
- validationMessages="@id('vmsgs')" : all validation messages from our custom validators can be accessed with this variable(vmsgs).
<label value="@load(vmsgs[firstNameTextbox])" style="color:red;"/>
Finally, we have to tell the form what to do when its submitted. This is done by assigning a 'command' to a button:
<button id="createButton" label="Create" onClick="@command('save'))" />
create-zul-viewmodel
This will create a zul and a corresponding view model wired together, without the need to have the composer extend BindComposer: That's it. The surface of MVVM in zkgrails.