public class AnnotateDataBinder extends DataBinder
The DataBinder that reads ZUML annotations to create binding info.
You have two ways to annotate ZK components. For ZK data binding, you can use @{...} annotaion expression or <a:bind> annotation expression.
To use <a:bind> annotation expression, in the ZUML page you must declare the XML namespace, xmlns:a="http://www.zkoss.org/2005/zk/annotation" first. Then declare <a:bind> before component to make the annotation.
We suggest annotating directly on the component property with intuitive @{...} expression because it is more readable.
For example, the following annotation associates the attribute "value" of the component "textbox" to the bean's value "person.address.city".
@{...} way:
<textbox value="@{person.address.city}"/>
The @{...} pattern tells the ZUML parser that this is for annotation.
<a:bind> way:
<a:bind value="person.address.city"/> <textbox/>
You can put more metainfo inside the @{...} or <a:bind> so this DataBinder knows what to do. The complete format is like this:
@{...} way:
<componentX attrY="@{bean's value,[tag='expression']...}"/>
<a:bind> way:
<a:bind attrY="bean's value;[tag:expression]..."/> <componentX/>
This associates the componentX's attribute attrY to the bean's value. The bean's value is something
in the form of beanid.field1.field2... You can either call DataBinder.bindBean(java.lang.String, java.lang.Object)
to bind the beanid to a
real bean object or you can neglect it and this DataBinder would try to find it from the variables map via
Page.getZScriptVariable(java.lang.String)
then Component.getAttributeOrFellow(java.lang.String, boolean)
method.
That is, all those variables defined in zscript are also accessible by this DataBinder. Note that you can choose
either two formats of annotations as your will and you
can even hybrid them together though it is not generally a good practice.
The tag='expression' or tag:expression is a generic form to bind more metainfo to the attrY of the componentX. The currently supported tags includes "load-when", "save-when", "access", "converter", "load-after"(since 3.6.1), and "save-after"(since 3.6.1).
The @{...} way that specify directly on the Component's attribute:
<textbox id="firstname" value="@{person.firstName}"/> <textbox id="lastname" value="@{person.lastName}"/> <label id="fullname" value="@{person.fullName, load-when='firstname.onChange,lastname.onChange'}"/>
Or the <a:bind> way that declare in front of the Component:
<a:bind value="person.firstName"/> <textbox id="firstname"/> <a:bind value="person.lastName"/> <textbox id="lastname"/> <a:bind value="person.fullName; load-when:firstname.onChange; load-when:lastname.onChange"/> <label id="fullname"/>
The @{...} way that specify directly on the Component's attribute:
<textbox id="firstName" value="@{person.firstName, save-when='self.onChange'}"/>
Or the <a:bind> way that declare in front of the Component:
<a:bind value="person.firstName; save-when:self.onChange"/> <textbox id="firstName"/>
However, you don't generally specify the save-when tag. If you don't specify it, the default events are used depends on the natural characteristic of the component's property as defined in lang-addon.xml. For example, the save-when of Label.value is default to "none" while that of Textbox.value is default to "self.onChange". That is, the following example is the same as the above one.
The @{...} way that specify directly on the Component's attribute:
<textbox id="firstName" value="@{person.firstName}"/>
Or the <a:bind> way that declare in front of the Component:
<a:bind value="person.firstName"/> <textbox id="firstName"/>
On the other hand, you might not specify the save-when tag nor you want the default events to be used. Then you can specify a "none" keyword or simply leave empty to indicate such cases.
<textbox id="firstName" value="@{person.firstName, save-when='none'}"/>or
<textbox id="firstName" value="@{person.firstName, save-when=''}"/>or
<a:bind value="person.firstName; save-when:none;"/> <textbox id="firstName"/>or
<a:bind value="person.firstName; save-when: ;"/> <textbox id="firstName"/>
DataBinder.loadAll()
and DataBinder.loadComponent(org.zkoss.zk.ui.Component)
would load only those attributes
with "both" or "load" access mode. The DataBinder.saveAll()
and
DataBinder.saveComponent(org.zkoss.zk.ui.Component)
would save only those attributes with "both" or "save" access mode. If you
don't specify it, the default access mode depends on the natural characteristic of the component's attribute
as defined in lang-addon.xml. For example, Label.value is default to "load" access mode while Textbox.value
is default to "both" access mode. For example, the following code snips tells DataBinder that Textbox "firstName"
would allowing doing save into bean only not the other way.
The @{...} way that specify directly on the Component's attribute:
<textbox id="firstName" value="@{person.firstName, access='save'}"/>
Or the <a:bind> way that declare in front of the Component:
<a:bind value="person.firstName;access:save;"/> <textbox id="firstName"/>
TypeConverter
interface.
It is used to convert the value between component attribute and bean field. Multiple definition is NOT allowed
and the later defined would override the previous defined one.
Most of the time you don't have to specify this since this DataBinder supports converting most commonly
used types. However, if you specify the TypeConverter class name, this DataBinder will new an instance and use
it to cast the class.
(Since 3.1) If you specify some tags other than the supported tags, they will be put into an argument Map
and is stored as a component's custom attribute (componentScope) with key name "bindingArgs" (no matter annotated
in which attribute of the component).
e.g.
Then mylabel.getAttribute("bindingArgs") will return a Map with {answer=yes, question=no} two entries (Since 3.1) We support the "distinct"
concept for collection components with "model" attribute(i.e. Grid, Listbox, Comobobox, etc.). You can
specify as follows to tell the Data Binder that there might be one same object in multiple entries. or The default value for distinct is "true". However, if you specify distinct=false, the DataBinder will
scan the whole ListModel to find out all items with the specified objects (thus worse performance if a
big ListModel). (Since 3.6.2) if you specify some tags other than the supported tags, they will be put into an argument Map
and is stored as a component's custom attribute(componentScope) with key name "Xxx_bindingArgs" where the Xxx
is the name of the annotated component attribute. e.g.
Then mylabel.getAttribute("value_bindingArgs") will return a Map with {answer=yes} entry and
mylabel.getAttribute("style_bindingArgs") will return another Map with {question=no} entry. Since 3.0.0, DataBinder supports validation phase before doing a save. Note that a DataBinder "save" is triggered by
a component event as specified on the "save-when" or "save-after" tag. Before doing a save, it first fires an onBindingSave
event to each data-binding component and then it fires an onBindingValidate event to the event triggering component before really saving
component property contents into bean's
property. So application developers get the chance to handle the value validation before saving. In the following example
when end user click the "savebtn" button, an "onBindingSave" is first fired to "firtName" and "lastName" textboxes and
then an "onBindingValidate" is fired to "savebtn" button. Application developers can register proper event handlers to do
what they want to do. Note that the original textbox constraint mechanism is still there. This DataBinder validation phase is an
add-on feature that can be applied to all components and attributes that use data binding mechanism.
<label id="mylabel" value="@{person.name, answer='yes'}" style="@{person.mystyle, question='no'}">
<grid model="@{persons, distinct=false}" ...>
...
</grid>
<a:bind model="persons; distinct:false"/>
<grid ...>
...
</grid>
<label id="mylabel" value="@{person.name, answer='yes'}" style="@{person.mystyle, question='no'}">
<textbox id="firstName" value="@{person.firstName, save-when="savebtn.onClick"}" onBindingSave="..."/>
<textbox id="lastName" value="@{person.lastName, save-when="savebtn.onClick"}" onBindingSave="..."/>
<button id="savebtn" label="save" onBindingValidate="..."/>
AnnotateDataBinderInit
,
DataBinder
,
Serialized Form_collectionItemMap, _collectionOwnerMap, ARGS, LOAD_ON_SAVE_TRIGGER_COMPONENT, NULLIFY, TEMPLATE, TEMPLATEMAP, VARNAME
Constructor and Description |
---|
AnnotateDataBinder()
Deprecated.
No argument constructor to be used by
AnnotateDataBinderInit . |
AnnotateDataBinder(Component comp)
Deprecated.
Constructor that read all binding annotations in the components inside the specified component (inclusive).
|
AnnotateDataBinder(Component[] comps)
Deprecated.
Constructor that read all binding annotations of the given components array.
|
AnnotateDataBinder(Component[] comps,
boolean defaultConfig)
Deprecated.
Constructor that read all binding annotations of the given component array.
|
AnnotateDataBinder(Component comp,
boolean defaultConfig)
Deprecated.
Constructor that read all binding annotations in the components inside the specified component (inclusive).
|
AnnotateDataBinder(Desktop desktop)
Deprecated.
Constructor that read all binding annotations of the components inside the specified desktop.
|
AnnotateDataBinder(Desktop desktop,
boolean defaultConfig)
Deprecated.
Constructor that read all binding annotations of the components inside the specified desktop.
|
AnnotateDataBinder(Page page)
Deprecated.
Constructor that read all binding annotations of the components inside the specified page.
|
AnnotateDataBinder(Page page,
boolean defaultConfig)
Deprecated.
Constructor that read all binding annotations of the components inside the specified page.
|
Modifier and Type | Method and Description |
---|---|
void |
init(Component[] comps,
boolean defaultConfig)
Deprecated.
Initialization that read all binding annotations of the given component array.
|
void |
init(Component comp,
boolean defaultConfig)
Deprecated.
Initialization that read all binding annotations in the components inside the specified component (inclusive).
|
void |
init(Desktop desktop,
boolean defaultConfig)
Deprecated.
Initialization that read all binding annotations of the components inside the specified desktop.
|
void |
init(Page page,
boolean defaultConfig)
Deprecated.
Initialization that read all binding annotations of the components inside the specified page.
|
addBinding, addBinding, addBinding, addBinding, addBinding, addBinding, addCollectionItem, bindBean, existBinding, existsBindings, getAllBindings, getBinding, getBindingCollectionItem, getBindings, init, isDefaultConfig, isLoadOnSave, loadAll, loadAttribute, loadComponent, loadPropertyAnnotation, removeBinding, saveAll, saveAttribute, saveComponent, setDefaultConfig, setLoadOnSave, setupTemplateComponent
public AnnotateDataBinder()
AnnotateDataBinderInit
.public AnnotateDataBinder(Desktop desktop)
desktop
- the ZUML desktop.public AnnotateDataBinder(Page page)
page
- the ZUML page.public AnnotateDataBinder(Component comp)
comp
- the ZUML component.public AnnotateDataBinder(Component[] comps)
comps
- the Component array.public AnnotateDataBinder(Desktop desktop, boolean defaultConfig)
desktop
- the ZUML desktop.defaultConfig
- whether load default binding configuration defined in lang-addon.xmlpublic AnnotateDataBinder(Page page, boolean defaultConfig)
page
- the ZUML page.defaultConfig
- whether load default binding configuration defined in lang-addon.xmlpublic AnnotateDataBinder(Component[] comps, boolean defaultConfig)
comps
- the Component arraydefaultConfig
- whether load default binding configuration defined in lang-addon.xmlpublic AnnotateDataBinder(Component comp, boolean defaultConfig)
comp
- the ZUML component.defaultConfig
- whether load default binding configuration defined in lang-addon.xmlpublic void init(Desktop desktop, boolean defaultConfig)
desktop
- the ZUML desktop.defaultConfig
- whether load default binding configuration defined in lang-addon.xmlpublic void init(Page page, boolean defaultConfig)
page
- the ZUML page.defaultConfig
- whether load default binding configuration defined in lang-addon.xmlpublic void init(Component[] comps, boolean defaultConfig)
comps
- the Component arraydefaultConfig
- whether load default binding configuration defined in lang-addon.xmlpublic void init(Component comp, boolean defaultConfig)
comp
- the ZUML component.defaultConfig
- whether load default binding configuration defined in lang-addon.xmlCopyright © 2005-2018 Potix Corporation. All Rights Reserved.