Create Data Binding Programmatically"
Line 8: | Line 8: | ||
# Initialize the binder | # Initialize the binder | ||
# Store data objects as attributes | # Store data objects as attributes | ||
+ | #: To make data be available for EL expressions | ||
# Add data bindings | # Add data bindings | ||
Line 13: | Line 14: | ||
''' Basic steps example''' | ''' Basic steps example''' | ||
− | <source lang="java" high=' | + | <source lang="java" high='3,10,12,14,15, 18'> |
public class DynamicBindingComposer extends SelectorComposer { | public class DynamicBindingComposer extends SelectorComposer { | ||
+ | |||
+ | private Binder binder = new DefaultBinder(); | ||
... | ... | ||
Line 25: | Line 28: | ||
comp.setAttribute("person", person); | comp.setAttribute("person", person); | ||
+ | binder.addPropertySaveBindings(firstNameBox, "value", "person.firstName", null, null, null, null, null,null,null); | ||
binder.addPropertyLoadBindings(firstNameBox, "value", "person.firstName", null, null, null, null, null); | binder.addPropertyLoadBindings(firstNameBox, "value", "person.firstName", null, null, null, null, null); | ||
− | |||
// add more data bindings... | // add more data bindings... | ||
− | binder.loadComponent(grid, true); //optionally, call | + | binder.loadComponent(grid, true); //optionally, call to load beans' data for the first time |
} | } | ||
</source> | </source> | ||
− | * Line | + | * Line 3: |
* Line 10: | * Line 10: | ||
+ | * Line 12: | ||
* Line 14: | * Line 14: | ||
+ | * Line 15: | ||
+ | * Line 18: | ||
Revision as of 01:20, 2 January 2013
Overview
Under MVC approach, getting component's attribute value by calling getter methods causes lots of routine code in a composer. But under MVVM approach, all attributes' values are saved to ViewModel's properties automatically without calling any methods because of data binding. Through using a binder to add data binding for components, we also can enjoy this benefit in a composer. This section introduces basic usages of a binder.
Binder API Usage
There are 3 basic steps to create data bindings:
- Initialize the binder
- Store data objects as attributes
- To make data be available for EL expressions
- Add data bindings
Basic steps example
public class DynamicBindingComposer extends SelectorComposer {
private Binder binder = new DefaultBinder();
...
@Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
binder.init(grid,this, null);
comp.setAttribute("person", person);
binder.addPropertySaveBindings(firstNameBox, "value", "person.firstName", null, null, null, null, null,null,null);
binder.addPropertyLoadBindings(firstNameBox, "value", "person.firstName", null, null, null, null, null);
// add more data bindings...
binder.loadComponent(grid, true); //optionally, call to load beans' data for the first time
}
- Line 3:
- Line 10:
- Line 12:
- Line 14:
- Line 15:
- Line 18:
Here we give some common examples, for more details please refer to Javadoc: Binder.
Property binding in a ZUL
<textbox value="@bind(vm.person.firstName)"/>
Programmatic property binding
binder.addPropertyLoadBindings(firstNameBox, "value", "vm.person.firstName", null, null, null, null, null);
binder.addPropertySaveBindings(firstNameBox,"value","vm.person.firstName", null, null, null, null, null,null,null);
String[] command = {"submit"};
binder.addPropertyLoadBindings(firstNameLabel, "value", "vm.person.firstName", null, command, null, null, null);
Form Binding
binder.addFormLoadBindings(grid, "fx", "vm.person", null, null, null);
binder.addFormSaveBindings(grid, "fx", "vm.person", command, null, null, null, null);
binder.addPropertyLoadBindings(firstNameBox, "value", "fx.firstName", null, null, null, null, null);
binder.addPropertySaveBindings(firstNameBox, "value", "fx.firstName", null, null, null, null, null
,"vm.emptyValidator",null);
<div apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('org.zkoss.reference.developer.mvvm.advance.DynamicFormBindingVM')"
validationMessages="@id('vmsgs')">
...
<row>
First Name:
<textbox id="fn"/>
<label id="fnError" style="color:red" />
</row>
binder.addPropertyLoadBindings(fNameErrorLabel, "value", "vmsgs[fn]", null, null, null, null, null);
Add Data Binding for Collections
Assume that we hope end users can edit an item directly in a Listbox. Hence we could put a Textbox in each Listcell and make the Textbox bind to a object of Listbox's model. This data binding cannot be made by writing annotation in a zul because those Textboxs are dynamically created.
<window apply="org.zkoss.reference.developer.mvvm.advance.DynamicCollectionBindingComposer"
width="600px">
...
<div apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('org.zkoss.reference.developer.mvvm.advance.DynamicCollectionBindingVM')">
<listbox model="@load(vm.personList)" selectedItem="@bind(vm.selectedPerson)" rows="10">
</listbox>
...
</div>
...
</window>
Use ItemRenderer
class MyListboxRenderer implements ListitemRenderer{
public void render(Listitem listitem, Object data, int index)
throws Exception {
//TODO explain why
listitem.setAttribute("each", data);
//first name
Listcell fnCell = new Listcell();
listitem.appendChild(fnCell);
Textbox fnBox = new Textbox();
fnBox.setInplace(true);
fnCell.appendChild(fnBox);
binder.addPropertyLoadBindings(fnBox, "value", "each.firstName", null, null, null, null, null);
binder.addPropertySaveBindings(fnBox, "value", "each.firstName", null, null, null, null, null, null, null);
//last name
...
//age
...
//delete button
...
}
}