`
snoopy7713
  • 浏览: 1140316 次
  • 性别: Icon_minigender_2
  • 来自: 火星郊区
博客专栏
Group-logo
OSGi
浏览量:0
社区版块
存档分类
最新评论

【zk开发】zk注解的秘密

    博客分类:
  • ZK
阅读更多

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)  thenComponent.getVariable(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).

  • load-when . You can specify the events concerned when to load the attribute of the component from the bean. Multiple definition is allowed and would be called one by one. Note that binding is executed BEFORE other event listeners you defined. (If you want the loading to be executed AFTER your event listener, use load-after). For example, the following code snip tells DataBinder that the attribute "value" of Label "fullName" will load from "person.fullName" when the Textbox "firstName" or "lastName" fire "onChange" event.

    The @{...} way that specify directly on the Component's attribute:

       注意第三个组件示例中load-when发生的时机:compId.onEventNameXXXX

     <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"/>
     
  • (Since 3.6.1) load-after . Similar to load-when. You can specify the events concerned when to load the attribute of the component from the bean. The only difference is that the loading is done AFTER  other event listeners listening to the same event are processed; while in load-when the loading is done BEFORE  other event listeners listening to the same event are processed.
  • save-when . You can specify the events concerned when to save the attribute of the component into the bean. Since ZK version 3.0.0, you can specify multiple events in save-when tag (i.e. before ZK 3.0.0, you can specify only one event). The events specified, if fired, will trigger this DataBinder to save the attribute of the component into the specified bean. Note that binding is executed BEFORE other event listeners you defined. (If you want the saving to be executed AFTER your event listener, use save-after). For example, the following code snip tells DataBinder that the property "value" of Textbox "firstName" will save into "person.firstName" when the Textbox itself fire "onChange" event.

    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"/>
     
  • (Since 3.6.1) save-after. Similar to save-when. You can specify the events concerned when to save the attribute of the component to the bean. The only difference is that the saving is doneAFTER  other event listeners listening to the same event are processed; while in save-when the saving is done BEFORE  other event listeners listening to the same event are processed.
  • access . You can set the access mode of the attrY of the componentX to be "both"(load/save), "load"(load Only), "save"(save Only), or "none"(neither).  save允许修改bean值,load仅访问属性值,both具有save/load二者功能  Multiple definition is NOT allowed and the later defined would override the previous defined one. The access mode would affects the behavior of the DataBinder's loadXxx and saveXxx methods. The DataBinder.loadAll()  andDataBinder.loadComponent(org.zkoss.zk.ui.Component)  would load only those attributes with "both" or "load" access mode. The DataBinder.saveAll()  andDataBinder.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"/>
     
  • converter.  可 以指定实现TypeConverter接口的converter类名字,它将负责组件属性和bean属性之间的互相转换.converter不允许配置多 个,如果定义多个那么后一个将覆盖前一个。大多说情况下你无需指定它,因为DataBinder支持大多说通常使用的类型,然后如果你指定 TypeConverter类名,那么DataBinder实例化这个转换器,替代默认转换器转换

(Since 3.1)如果你指定了其他的非特定的标签,那么他们将被放入map参数中,作为组件属性(key=bindingArgs)存储在组件作用域内,例如 <label id="mylabel" value="@{person.name, answer='yes'}" style="@{person.mystyle, question='no'}">

 然后 mylabel.getAttribute("bindingArgs") 将返回{answer=yes, question=no}两个记录, (自从 3.1)我们支持"distinct" 的概念,用于具有model属性的组件(即Grid, Listbox, Comobobox, 等等.).你可以像下面那样指定该属性告诉 Data Binder 多条记录中或许有相同的对象


 <grid model="@{persons, distinct=false}" ...>
    ...
 </grid>
 

or


 <a:bind model="persons; distinct:false"/>
 <grid ...>
    ...
 </grid>
 

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

 

自从 3.6.2,如果你指定非特定标签,那么他们将被放入map参数中,并存储在以Xxx_bindingArgs命名的组件作用域内容, 其中Xxx表示注解组件属性的名字


 <label id="mylabel" value="@{person.name, answer='yes'}" style="@{person.mystyle, question='no'}"> 
 

然后 mylabel.getAttribute("value_bindingArgs") 返回{answer=yes} , mylabel.getAttribute("style_bindingArgs") 返回另外一个map{question=no} entry.

 

自从3.0.0,DataBinder 支持保存前验证阶段,注:DataBinder "save"由save-when或者save-after指定事件触发时执行的行为。 在保存之前,首先触发注解绑定组件的onBindingSave事件,然后在触发onBindingValidate事件 ,在实际保存组件属性内容到bean属性之前触发 ,因此应用开发者可以在保存之前处理输入值的验证, 在下面的例子中,当user点击savebtn按钮结束以后,onBindingSave发送到firtName和lastName文本框,然后 onBindingValidate事件发送到savebtn按钮.应用开发者可以注册适当的事件处理程序做他们想做的事情

 <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="..."/>
 

注意:textbox原有的约束机制让然起作用,该DataBinder验证阶段仅是一个附加特性,它可以用于所有组件的所有属性,

 

 

Since:
2.4.0 Supporting @{...} annotations., 3.0.0 Supporting multiple events of save-when tag and validation phase., 3.1.0 Supporting bidningArgs; suport "distinct" on collection data binding., 3.6.1 Support load-after, save-after, 3.6.2 Support Xxx_bindingArgs
Author:
Henri Chen


以下内容摘自官网,版权归zkoss.org


注释

注释提供了关于一个组件的数据,这些数据并不属于组件本身。它们在所注释组件的操作上并没有直 接的影响。而是,它们在运行时被检测(examine),主要由工具或管理者(a tool or a manager)使用。注释的内容和意义完全取决于开发人员使用的工具或管理者。例如,一个数据绑定(data-binding)管理者可以检测注释,以 知道组件值要被存储的数据源。

注释ZUML页面

注释可被用于ZUML页面中组件和属性的声明。有两种注释方式:标准的方式和简单的方式(the classic way and the simple way)。选择娜种看你的喜好。若喜欢的话可以在同一页面内混合使用它们。

注释组件声明的标准方式

注释要放在你想注释的元素声明之前:

 

 

 

<window xmlns:a="http://www.zkoss.org/2005/zk/annotation">
   <vbox>
      <a:author name="John Magic" date="3/17/2006"/>
      <listbox>
      </listbox>
...

 

annotation为http://www.zkoss.org/2005/zk/annotation 空间内的一个元素。元素的名字和属性可以是依赖于你所使用工具的一切。你可以使用几个注释为相同的组件声明注释:

 

 

 

<a:author name="John Magic"/>
<a:editor name="Mary White" date="4/11/2006"/>
<listbox/>

 

author和editor为注释的名称,而name和date为属性名称。换言之,注释由名称和属性映射组成。

若两个注释有相同的名称,则它们会被合并为一个注释。例如,

 

 

 

<a:define var1="auto"/>
<a:define var2="123"/>
<listbox/>

 

等价于

 

 

 

<a:define var1="auto" var2="123"/>
<listbox/>

 

[注]: 注释不支持EL表达式。

注释属性(Property)声明的标准方式

为注释一个属性声明,你可以将注释放置于属性声明之前,如下所示。

 

 

 

<listitem a:bind="datasource='author',name='name'" value="${author.name}"/>

 

或者,你可以使用attribute 元素,然后简单的注释属性声明,类似于为组件声明注释。换言之,上面的注释等价于下面的注释:

 

 

 

<listitem>
   <a:bind datasource="author" name="name"/>
   <attribute name="value">${author.name}</attribute>
</listitem>

 

注:若忽略了属性名称,则名称为value 。例如,

 

 

 

<listitem a:bind="value='selected'" value=""/>

 

等价于

 

 

 

<listitem a:bind="selected" value=""/>

 

注释属性声明的简单方式

除了如上描述的使用特定XMl命名空间进行注释,有一种简单的注释属性的方法:为要注释的属性使用注释表达式指定一个值,如下所示。

 

 

 

<listitem label="@{bind(datasource='author',selected)}"/>

 

注释表达式的格式为@{  annot-name  (  attr-name1  =  attr-value1,attr-name2=attr-value2  )} 。换言之,若属性值为一个注释表达式,则会被认为是为相应属性的注释,而不是其值。在上面的例子中,名为bind 的注释为label 属性注释。因此,其等价于

 

 

 

<listitem a:bind=" datasource='author',selected" label=""/>

 

若没有指定注释名称,则假定名称为default 。例如,下面的代码片断使用了default 作为注释名称为label 属性注释,且注释有一个属性,名称和值分别为valueselected.name

 

 

 

<listitem label="@{selected.name}"/>

 

换言之,等价于下面的代码片断:

 

 

 

<listitem label="@{default(value='selected.name')}"/>

 

注:你可以使用多个注释为相同的属性注释,如下所示。

 

 

 

<listitem label="@{ann1(selected.name) ann2(attr2a='attr2a',attr2b)}"/>

 

注释组件声明的简单方式

类似的,你可以通过为一个名为self 的特定属性指定注释表达来注释一个组件。

 

 

 

<listitem self="@{bind(each=person)}"/>

 

self 为一个关键字,表示注释被用于注释组件声明,而不是任何属性。换言之,等价于

 

 

 

<a:bind each="person"/>
<listitem/>

 

手动注释组件

通过使用org.zkoss.zk.ui.sys.ComponentCtrl 接口的addAnnotation  方法,你可以在运行时注释一个组件。

 

 

 

Listbox listbox = new Listbox();
listbox.addAnnotation("some", null);

 

获取注释

可以在运行时取回(retrieved back)注释。通常由工具获取,例如数据绑定管理者,而不是应用程序。换言之,为某一特定目的,应用程序注释ZUML页面以告诉工具如何处理组件。

下面为转储(dump)一个组件所有注释的例子:

 

 

 

void dump(StringBuffer sb, Component comp) {
   ComponentCtrl compCtrl = (ComponentCtrl)comp;
   sb.append(comp.getId()).append(": ")
     .append(compCtrl .getAnnotations()).append('\n');

   for (Iterator it = compCtrl.getAnnotatedProperties().iterator(); it.hasNext();) {
      String prop = it.next();
      sb.append(" with ").append(prop).append(": ")
         .append(compCtrl .getAnnotations(prop)).append('\n');
   }
}
分享到:
评论

相关推荐

    zk框架中的注解使用

    zk框架中的一些注解使用,项目中的需要用到的,各位可以了解一下,希望可以帮到大家!今后可以多交流,相互学习,共同进步。

    Zk中注解的使用(ZkDemo系列)

    在ZK框架中,注解的使用是提升开发效率和代码可读性的重要手段。ZK是一个基于组件模型的Java Web开发框架,它允许开发者创建富客户端用户界面,而无需处理复杂的JavaScript和浏览器兼容性问题。本文将深入探讨ZK中...

    ZK框架开发手册

    ZK框架还支持使用注解来简化开发过程,包括在ZUML和Java代码中使用注解。开发者可以在组件定义中添加注解来增强组件的功能,同时也可以通过注解来检索注解信息。 MVVM(Model-View-ViewModel)模式是ZK框架中用于...

    zk+spring+hibernate(全部用注解)

    在这个`zk+spring+hibernate(全部用注解)`的项目中,我们将探讨如何完全利用注解来配置和管理这些框架,从而实现更加简洁、高效的代码结构。 `ZK`,全称ZooKeeper,是一个分布式的、开放源码的分布式应用程序协调...

    ZK+spring+hibernate的整合

    Spring可以通过ZK的@Wire注解自动将Bean注入到ZK组件中。 4. **配置ZK-Spring**:需要引入ZK-Spring的库,这是一个连接ZK和Spring的桥梁,它提供了Spring的ApplicationContext到ZK Session的绑定,使得ZK组件可以...

    zk入门.web框架

    本篇文章将深入探讨ZK框架的基本概念、开发环境的搭建以及一些核心功能的使用。 **一、ZK插件安装** ZK的开发工具主要包括ZK Studio和ZK Package。ZK Studio是一个集成开发环境,可以作为Eclipse或Myeclipse的插件...

    ZK开发指南

    ### ZK开发指南知识点概述 #### 一、Overture(序言) ZK是一个高性能的Web应用程序框架,它使用Java语言编写,支持AJAX技术,能够帮助开发者快速构建丰富的交互式用户界面。ZK框架的核心优势在于其轻量级、易用性...

    zk十分钟入门demo

    通过`@Listen`注解,ZK将自动绑定`showMessage`方法到ZUL文件中的事件。 **总结** "zk十分钟入门demo"旨在帮助初学者快速上手ZK开发。通过"gettingStarted-master"中的示例,我们可以看到ZK如何使用ZUL文件构建用户...

    ZK数据绑定

    1. 属性绑定:这是ZK数据绑定的基础,通过`&lt;bind&gt;`或`@bind`注解将UI组件的属性(如文本框的文本)与数据模型的某个属性关联。例如,可以将文本框的`value`属性绑定到模型对象的`name`属性,当模型对象的`name`属性...

    zk+spring+hibernate整合

    在IT行业中,`ZK`(ZooKeeper)、`Spring`和`Hibernate`都是非常重要的技术组件,分别在分布式协调、应用框架和对象关系映射领域有着广泛应用。本项目是将这三个技术进行整合,用于构建一个基于MySQL数据库的完整...

    小型在线销售系统ZK+hibernate

    1. **ZK框架**:ZK是一个Java开发的富客户端用户界面框架,它专注于提供直观、高效的Web界面。ZK的组件模型使得开发者可以像操作桌面应用一样创建Web应用,同时其事件驱动机制简化了用户交互的处理。 2. **...

    zk 数据绑定(grid进行嵌套显示数据)

    3. `@Wire`: 注解用于在组件上指定绑定的属性,让ZK知道哪些组件应该与哪个模型字段对应。 二、ZK Grid组件 Grid是ZK中常用的表格组件,用于展示二维数据。它支持各种操作,如排序、分页、选择和编辑等。在ZK Grid...

    Publishing.ZK.Developers.Guide pdf 书中代码

    《Publishing.ZK.Developers.Guide》是一本专注于ZK框架开发的指南,由Packt Publishing出版。这本书深入介绍了ZK,一个基于组件的Java Web用户界面(UI)框架,用于构建富互联网应用程序(RIA)。ZK以其事件驱动、...

    ZK MVC与MVVM模式联合实现动态分页

    ZK也支持MVVM模式,通过`&lt;bind&gt;`标签和`@Listen`注解,可以方便地实现数据双向绑定。 在ZK MVC与MVVM联合实现动态分页的场景中,我们通常会这样做: 1. **模型(Model)**:在模型中,我们需要处理数据的获取和...

    zk+dubbo+spring本地工程

    【标题】"zk+dubbo+spring本地工程"指的是一个整合了Zookeeper、Dubbo和Spring框架的本地开发环境。这个项目可能是一个分布式服务治理的示例或者开发模板,旨在帮助开发者快速搭建具备服务注册与发现、远程调用等...

    zk+sptingmvc+ibatis 系统

    "ZK+SpringMVC+Ibatis"是一个常见的企业级应用开发框架组合,它整合了三个强大的技术:ZK作为用户界面的展示层框架,SpringMVC作为控制层框架,而Ibatis则作为数据访问层的持久化工具。这个系统的构建旨在提供高效、...

    ZK入门例子

    本教程将带领您深入了解如何使用Eclipse集成开发环境,结合ZK、Hibernate和MySQL,构建一个完整的网站应用。ZK是一个轻量级的Java Web UI框架,专注于提供丰富的用户界面组件和事件处理机制,而Hibernate是流行的...

    ZK 国际化(动态切换资源文件)1.0

    6. **ZK组件的本地化**:每个ZK组件都支持本地化,通过设置`label`属性或使用`@Label`注解指定资源文件中的键。当资源文件更新时,组件的标签会自动与新的资源值同步。 7. **全球化策略**:在大型项目中,可能会...

    springboot+dubbo+zk

    本项目通过"springboot+dubbo+zk"的组合,实现了基于注解方式的SpringBoot与Dubbo集成,从而减少了XML配置,提升了开发效率。 首先,SpringBoot是由Pivotal团队提供的一个用于简化Spring应用初始搭建以及开发过程的...

Global site tag (gtag.js) - Google Analytics