BindComposer
To enable the data binding in the ZUL, you have to apply a BindComposer on a component (said Root
component of this data binding). The BindComposer
implements Composer and plays a role to activate data binding mechanism for a component and its children components. It also initializes a Binder and ViewModel and passes ViewModel object's reference to Binder.
Apply BindComposer
To use a ViewModel you have to apply a BindComposer by setting “org.zkoss.bind.BindComposer” to “apply” attribute of a component.
<window id="win" apply="org.zkoss.bind.BindComposer">
<!-- other components inside will have data binding ability-->
</window>
Since 8.0.0
In ZK 8, BindComposer is auto-applied when the attribute of viewModel is being used. Notice that if you want to use another Composer, you will need to apply the BindComposer yourself.
Initialize a ViewModel
You also have to specify ViewModel's full-qualified class name to initialize it and give it an ID. The typical usage is like:
<window id="win" apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('foo.MyViewModel')">
<label value="@load(vm.message)"/>
<!-- other components -->
</window>
In above code example, after the target component, window, is composed, the BindComposer
will try to resolve the string literal inside @init()
as a Class
object and instantiate it. If it succeeds, it
will store ViewModel object as an attribute of the root component for future use and it stores with the key vm which is specified in @id
. Therefore, any child component of <window>
can reference ViewModel by the id vm.
If there is no ViewModel attribute specified, the binder itself will become the ViewModel. That means you can apply a ViewModel which inherit BindComposer
without specifying ViewModel attribute, but we only suggest this usage for experienced ZK user.
Wire Variable Automatically
If a member field is annotated by @WireVariable
in a ViewModel, the variable (if existed) will be wired into this field automatically before connecting Binder and ViewModel. Read Wire Variable for more detail
about wiring variables. Following is a example that shows how to wire a messagService
variable to the ViewModel.
public class OrderVM {
@WireVariable
MessageService messageService;
//rest of the class...
}
Initialize Binder
If you don't specify a root component's binder attribute, BindComposer
creates AnnotateBinder
by default. You usually don't have to specify binder attribute unless you want to use your own binder. You can get the Binder
object by invoking getAttribute("binder")
on the root component. In above example, it's win.getAttribute("binder")
. We only suggest this usage to experienced ZK users.
Initialize Validation Message Holder
The validate message holder is also created by BindComposer. It's a container of validation messages that are generated by Validator during validation. Before using validation message holder, we have to give it an id in validationMessages attribute. We can retrieve validation message from it with a component as a key. We'll describe the detail in section
<window title="Order Management" border="normal" width="600px"
apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init(orderVm)"
validationMessages="@id('vmsgs')">
<hlayout>
<intbox id="qbox" value="@load(vm.selected.quantity)
@save(vm.selected.quantity, before='saveOrder')
@validator(quantityValidator)"/>
<label value="@bind(vmsgs[qbox])" sclass="red" />
</hlayout>
</window>
- Give validation message holder an id in order to reference it. (line 3)
- We can retrieve validation messages of a input component, it's qbox, with the component as a key. (line 8)