Monday, 28 May 2012

ZK Data Binding


This is based on ZK 5 Data binding using Data Bind Manager org.zkoss.zkplus.databind.AnnotateDataBinderInit

Data binding is a mechanism that automates the data-copy plumbing code (CRUD) between UI components and the  data source. Application developers only have to tell the data binding manager about the associations between UI components and the data source. Then, the data -binding manager will do all the loading (loading data from the data source to UI components) and saving (saving data from UI component into the data source) jobs automatically
Now, let us start with simple example. You can find more details in ZK 5 Developer Reference Document.
The following example uses MVC Pattern design + ZK 5 Data binding concepts.

Step 1:
Create ZK Project as shown.
image
Step 2:
First of all, we have to define a data source as a data bean. In this example, we use Person class as an example
that holds the information of a person, say, first name, and last name
image
Here is the Code
package mydomain;
 
public class Person {
 
    private String _firstName = "";
    private String _lastName = "";
 
    // getter and setters
    public void setFirstName(String firstName) {
        _firstName = firstName;
    }
 
    public String getFirstName() {
        return _firstName;
    }
 
    public void setLastName(String lastName) {
        _lastName = lastName;
    }
 
    public String getLastName() {
        return _lastName;
    }
 
    public void setFullName(String f) {
        // do nothing.
    }
 
    public String getFullName() {
        return _firstName + " " + _lastName;
    }
 
}

Step 3:



Activates Data Binding Manager

The Data Binding Manager can be activated by defining the page Initializer at the top of every page.
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>


Demo.zul File


<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit"?>
<?page title="new page title" contentType="text/html;charset=UTF-8"?>
<zk>
    <window title="ZK Data Binding" border="normal">
 
        <grid width="400px">
            <rows>
                <row>
                    First Name:
                    <textbox  />
                </row>
                <row>
                    Last Name:
                    <textbox  />
                </row>
                <row>
                    Full Name:
                    <label  />
                </row>
            </rows>
        </grid>
    </window>
</zk>

Step 4:



Associate UI Components with Data Source


After adding the source data and activating the data-binding manager, you have to define the required UI objects and then associate them with the data source. ZUML annotation expression can be used to tell the data-binding manager the relationship between the data source and UI components. Its usage is very straightforward, simply by declaring the annotation into the component's attribute directly.
<component-name attribute-name="@{bean-name.attribute-name}'''"'''/>

Example

<textbox value="@{person.firstName}"


Data binding works with ZK MVC such as that:
1. Controller class provides a getter method to obtain the bean, or Collection.
2. Declare the bean, or Collection, as the value for a UI component in ZUL. The data binder will call the Controller class' getter method to append data to UI.


Modified Demo.Zul File


<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit"?>
<?page title="new page title" contentType="text/html;charset=UTF-8"?>
<zk>
    <window id="win" title="ZK Data Binding" border="normal" apply="UI.DemoComposer">
 
        <grid width="400px">
            <rows>
                <row>
                    First Name:
                    <textbox  value="@{win$DemoComposer.person.firstName}"/>
                </row>
                <row>
                    Last Name:
                    <textbox  value="@{win$DemoComposer.person.LastName }"/>
                </row>
                <row>
                    Full Name:
                    <label  />
                </row>
            </rows>
        </grid>
    </window>
</zk>


Modified  DemoComposer.Java


package UI;
 
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Textbox;
 
import mydomain.Person;
 
 
public class DemoComposer extends GenericForwardComposer {
 
    
    Person person = new Person();
    public void doAfterCompose(Component comp) throws Exception {
        super.doAfterCompose(comp);
        //prepare the example person object
        person.setFirstName("George");
        person.setLastName("Bush");
    }
    
    public String getFirstName()
    {
        return person.getFirstName();
                
    }
 
    public String getLastName()
    {
        return person.getLastName();
                
    }
 
}




Please remember the following always
Data binding works with ZK MVC such as that:
1. Controller class provides a getter method to obtain the bean, or Collection.
2. Declare the bean, or Collection, as the value for a UI component in ZUL. The data binder will call the Controller class' getter method to append data to UI.


In the composer, instead of writing getter for each property, we can get return the object of the bean as follows without changing any thing on the zul file as shown below



package UI;

import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Textbox;
import mydomain.Person;


public class DemoComposer extends GenericForwardComposer {
    Person person = new Person();


    public void doAfterCompose(Component comp) throws Exception {
        super.doAfterCompose(comp);
        // prepare the example person object
        person.setFirstName("George");
        person.setLastName("Bush");
    }


    /*
     * public String getFirstName() { return person.getFirstName(); } public
     * String getLastName() { return person.getLastName(); }
     */
    public Person getPerson() {
        return this.person;
    }
}


2 comments:

  1. Great example!
    Unfortunately outdated since ZK 7 release.. =[
    Would you explain us how to achieve the same without using the (now deprecated) AnnotateDataBinderInit?

    Best regards

    ReplyDelete