From Documentation

Jump to: navigation, search

  • Author
    Henri Chen, Principal Engineer, Potix Corporation
  • Date
    October 21, 2011
  • Version
    ZK 6



ZK Bind is a whole new data binding system with new specifications and implementations. Based on the experiences learned from databinder 1 and taking into account suggestions and feedback from users and contributors, we have created this easy to use, flexible, feature rich new data binding system in ZK6.


A whole new, clean annotation expression

  • Java style annotation expressions in zul: The new ZK annotation is consistent with Java's annotation style. If you know the Java style, you know the ZK Style.
  • A set of collaborated annotations: ZK Bind uses a set of annotations to make the use of data binding as intuitive and clear as possible.
    • @id(...): used to idientify a instance's id , ex a view model or a form.
    • @init(...): used to init a instance
    • @load(...): used to bind data and command along with parameters for loading data to target
    • @save(...): used to bind data and command along with parameters for saving data.
    • @bind(...): used to bind data along with parameters for both loading and saving.
    • @converter(...): used to specify converter along with parameters
    • @valiator(...): used to specify validator along with parameters
    • @command(...): used to bind an event to a command along with parameters.

EL 2.2 flexible expressions

  • ZK Bind accepts EL 2.2 syntax expressions in which you can provide flexible operations easily.
  • Bind to bean properties, indexed properties, Map keys seamlessly.
  • Bind to component custom attributes automatically.
  • Bind to Spring, CDI, and Seam managed bean automatically.
<image src="@load(vm.person.boy ? 'boy.png' : 'girl.png')"/>
<button onClick="@command(vm.add ? 'add' : 'update')" label="@load(vm.add ? 'Add' : 'Update'"/>
<button onClick="@command('subscribe')" disabled="@load(empty vm.symbol)" label="Subscribe"/>

One way load only data binding

  • Load when bean property changes
  • Conditional load after/before executing a command
  • Multiple conditional load before/after executing different/same commands
<label value="@load(vm.person.fullname)"/>
<label value="@load(vm.person.firstname, after='update')"/>
<label value="@load(vm.person.firstname, before='delete')"/>
<label value="@load(vm.person.firstname, after={'update','delete'})"/>
<label value="@load(vm.person.firstname, after='update') @load(vm.person.message, after='delete'})"/>

One way save only data binding

  • Save when UI component attribute changes
  • Multiple save to property of different target beans
  • Conditional save before/after executing a command
  • Multiple conditional save before/after executing different/same commands
<textbox value="@save(vm.person.firstname)"/>
<textbox value="@save(vm.person.firstname) @save(vm.tmpperson.firstname)"/>
<textbox value="@save(vm.person.firstname, before='update')"/>
<textbox value="@save(vm.person.firstname, after='delete')"/>
<textbox value="@save(vm.selected.firstname, before={'update','add'})"/>

Initial data binding

  • Loads when UI components are first added into the binding system
<label value="@init(vm.selected.firstname)"/>

Two way data binding

  • Multiple conditional load and save on different back-end beans before/after executing different/same commands
<textbox value="@load(vm.selected.firstname) @save(vm.selected.firstname) @save(vm.newperson.firstname,before='add')"/>
  • Short expression for both save and load bindings without command condition.[1]
<textbox value="@bind(vm.person.firstname)"/>

  1. @bind(...) is shortcut for "@load(...) @save(...)", and @save is automatically ignored if the property doesn't support it

Bind to any attributes of the UI components

  • Bind symmetrically to all attributes of UI components
<textbox value="@bind(vm.symbol)" instant="true"/>
<button disabled="@load(empty vm.symbol)" label="Subscribe" />

Event command binding

  • Bridge ZK event to command
  • Automatic event listener registration
  • Simple command name invocation
<button onClick="@command('subscribe')" disabled="@load(empty vm.symbol)" label="Subscribe" />

Template/Collection binding

  • Binding on Listbox/Grid/Tree/Combobox
  • Local variable scope is limited to the container component
  • Support index property
<listbox width="300px" model="@load(vm.albumList)" selectedItem="@bind(vm.selectedAlbum)" vflex="true">
    <template name="model" var="a">
        <listitem label="@load(a.title)"/>

Form binding

  • Middle form binding to avoid affecting back-end data beans
  • Submit a form in a whole
  • Conditional save for different commands
<grid form="@id('fx') @load(vm.selected) @save(vm.selected, before='update') @save(vm.newAlbum, before='add')">
    <row>Title: <textbox value="@bind(fx.title)"/></row>
    <row>Artist: <textbox value="@bind(fx.artist)"/></row>
    <row><checkbox checked="@bind(fx.classical)"/> Classical</row>
    <row>Composer: <textbox value="@bind(fx.composer)"/></row>
<button onClick="@command('add')" label="Add"/>
<button onClick="@command('update')" label="Update"/>

Java annotated data dependency tracking

  • Controllable load on save
  • @NotifyChange to notify property changes
  • @DependsOn to specify property change dependency
@NotifyChange //notify firstname change
public void setFirstname(String fn) {
    firstname = fn;

@NotifyChange //notify lastname change
public void setLastname(String ln) {
    lastname = ln;

@DependsOn({"firstname","lastname"}) //full name will change if either firstname and/or lastname change
public String getFullname() { 
    return firstname + " " + lastname;

Embedded validation cycle

  • Bind validator by name or by EL expression
  • Embedded system Validator: provide commonly used validators in which users can use directly by only specifying the name
  • Validate a single property or a form
  • Validate on a command
<textbox value="@save(vm.selected.firstname) @validator('noEmpty')"/>
<grid form="@id('fx') @load(vm.selected) @save(vm.selected, before='update') @validator(vm.passwordValidator)">
    <row>username<textbox value="@bind(fx.username)"/></row>
    <row>password<textbox value="@bind(fx.password)" type="password"/></row>
    <row>retype password<textbox value="@bind(fx.retypePassword)" type="password"/></row>

Enhanced converter mechanism

  • Bind converter by name or by EL expression
  • Embedded system Converters: provide commonly used converters in which users can use directly by only specifying the name
<datebox value="@bind(vm.selected.birthday) @converter('formatedDate', format='yyyy/MM/dd')"/>


  • Ease UI components, binder, and ViewModel association
  • Each binder covers only the applied component tree
  • Inter-binder communications
<window apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('org.zkoss.mvvm.examples.album.AlbumViewModel')">

Bind on demand

  • Supports dynamic add/remove bindings by API.
  • Attached components with binding annotations are automatically managed by the existing binder if covered.
  • Detached components that were managed by a binder are automatically removed from the binding management.

Support seamless MVVM design pattern

  • Utilize MVVM design pattern to achieve separation of data and logic from presentation easily.
    • UI Design and ViewModel can be implemented independently and in parallel.
    • Ability to add new Views or change current Views easily.
    • Different Views for different devices with a common ViewModel.
    • Allow unit-test ViewModel independently without UI environments.

For details about how to apply MVVM design pattern with ZK Bind, please see this series of Small Talks [1][2][3].

Download and Resources

To test out new features please download our latest freshly builds here.


Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.
You got stuck here?
Let us know how we can improve this page
For specific questions please use the forum