Create Data Binding Programmatically"

From Documentation
Line 112: Line 112:
  
  
 +
<source lang="java">
 +
 +
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
 +
...
 +
}
 +
 +
}
  
 
== Use Template==
 
== Use Template==

Revision as of 22:16, 27 December 2012

Overview

when you need to add a data binding programmatically.


Binder API Usage

There are 3 basic steps to create data bindings:

  1. Get the binder
  2. add data bindings
  3. load binding at the beginning. (why? seem extra for users)

Assume we have a ViewModel inside a composer:

	<window apply="org.zkoss.reference.developer.mvvm.advance.DynamicBindingComposer" width="600px">
		<grid  apply="org.zkoss.bind.BindComposer"
	viewModel="@id('vm') @init('org.zkoss.reference.developer.mvvm.advance.DynamicBindingVM')">
...

Basic steps example

public class DynamicBindingComposer extends SelectorComposer {
	...

	@Override
	public void doAfterCompose(Component comp) throws Exception {
		super.doAfterCompose(comp);
		
		binder = (Binder)grid.getAttribute("binder");
		
		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);
		// add more data bindings...
		
		binder.loadComponent(grid, true);
	}


<textbox value="@bind(vm.person.firstName)"/>
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

<source lang="java">

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 ... }

}

Use Template