The Concept of Data Binding

From Documentation

Stop.png This article is out of date, please refer to http://books.zkoss.org/zkessentials-book/master/ for more up to date information.



ZK's annotated data binding mechanism involves the following players to make it work:

  • Data Bean
  • ZK UI Components declared in ZUL file
  • ZK's annotated data binding manager utility

In a nutshell, a bean's particular property is associated with a specified component attribute, such as that whenever a value is modified, the annotated data binding manager will call the data bean's getter and setter methods to keep the values in sync between the bean and the component.
The syntax for declaring this association in ZUML is

<component-name attribute-name="@{bean-name.attribute-name}"/>

A Basic Example of ZK Annotated Data Binding

Here we will walk through a basic annotated data binding sample step by step.

Preparing the Data Bean

Create a data object "Person" with two properties:

public class Person {
    private String _firstName = "";
    private String _lastName = "";
    private Boolean _married = true;
 
    public Person(){
    	
    }
    public Person(String firstName, String lastName, Boolean married){
    	_firstName = firstName;
    	_lastName = lastName;
    	_married = married;
    }
    
    // getter and setters
    
 
    public void setFullName(String f) {
        // do nothing
    }
 
    public String getFullName() {
        return _firstName + " " + _lastName;
    }
}

Declare the data bean in ZUL file

Instantiate the Person class in zscript:

<window>
    <zscript><![CDATA[
        //prepare the person object
       	import bean.Person;
        Person person = new Person();
        person.setFirstName("Max");
        person.setLastName("Planck");
    ]]>
    </zscript>
    // UI declaration
</window>

Activate the Annotated Data Binding Manager

We activate the data binding manager by declaring the page initiator. Then the initiator will do the following automatically for us:

  1. Create an instance of AnnotateDataBinderInit.
  2. Sets the AnnotateDataBinder instance as a variable with the name "binder" stored in the component as specified in arg0 "component-path"(if arg0 is not specified, use Page instead).
  3. Calls DataBinder.loadAll() to initiate all UI components from the associated data source.
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>

Declare Components for Annotated Data Binding

Now we declare the components in our ZUL file to apply the annotated data binding mechanism:

<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>
<window>
    <zscript><![CDATA[
        //prepare the person object
       	import bean.Person;
        Person person = new Person();
        person.setFirstName("Max");
        person.setLastName("Planck");
    ]]>
    </zscript>
    <grid width="400px">
        <rows>
            <row> First Name: <textbox value="@{person.firstName}"/></row>
            <row> Last Name: <textbox value="@{person.lastName}"/></row>
            <row> Full Name: <label value="@{person.fullName}"/></row>
        </rows>
    </grid>
</window>

The result is a table with 3 rows, when user enters values in the textboxes and an onChange event is fired, the lable in the last row is updated instantly. ZKEssentials DisplayInGrid BasicDataBinding.png

A Basic Example of Annotated Data Binding with a Collection

The sample code below illustrates how to populate data using a Collection in a UI component:

<?page title="Data binding 5" contentType="text/html;charset=UTF-8"?>
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>
<window title="Data binding 5" border="normal">
  <zscript><![CDATA[ 
     //prepare the sample List
     	import bean.Person;
        int count = 3;
        List persons = new ArrayList();
        for(int j= 1; j <= count; ++j) {
            Person personx = new Person();
            personx.setFirstName("Leohnard"+j);
            personx.setLastName("Euler"+j);      
            persons.add(personx);
        }
     ]]></zscript>
 
    <listbox rows="4" model="@{persons}">
        <listhead>
            <listheader label="First Name" width="100px" />
            <listheader label="Last Name" width="100px" />
            <listheader label="Full Name" width="100px" />
        </listhead>
        <!-- define variable person here-->
        <listitem self="@{each='person'}">
            <listcell>
                <textbox value="@{person.firstName}" />
            </listcell>
            <listcell>
                <textbox value="@{person.lastName}" />
            </listcell>
            <listcell label="@{person.fullName}" />
        </listitem>
    </listbox>
</window>

At line 2, we declare an initiator for the annotated data binder. From line 4 through 14, we prepare the data collection. In this example, we dynamically generate a list of the Person data objects and iteratively set the first and last names for each. Since we are using the data collection to populate the Listbox component, we use ZK's annotated data binding syntax to assign it with a data model (line 17); in this case, persons is the data collection we instantiated earlier in zscript will be applied to the data binder. For each Listitem (an listitem in listbox is analogous to a row in grid), we assign each with a Person object and the object's attributes (first name, last name, full name) to each cell of the listitem. When this simple composition, we are able to populate the whole Listbox with our "Persons" data collection.

Let's summarize what needs to be done for annotated data binding a UI component with a data collection:

  1. declare the initiator for annotated data binder (line 2)
  2. prepare the data collection (zscript is used in this sample, the Java code can be placed in an controller class instead)
  3. annotate the UI component (Grid, Listbox) for data binding with the data collection name (line 17)
  4. annotate the row element (Listitem for Listbox; Row for Grid) with the data object (Person) by iterating through data object collection (Persons).
  5. annotate each cell in the row element with the respective data object property

ZKEssentials DisplayInGrid DatabindingCollection.png



Last Update : 2013/12/09

Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.