原博写得不错,转载到此备忘:关于apply属性使用的一些例子
通过指定apply的内容调用UI层的不同方法。
ZUL:
<zk>
<!--方式一 <window title="composer1 example" width="300px" apply="com.ui.MyComposer" border="normal"> -->
<!--方式二 <window title="composer1 example" width="300px" apply="com.ui.MyComposer1" border="normal"> -->
<!--方式二 <window title="composer1 example" width="300px" apply="com.ui.MyComposer2" border="normal"> -->
<window title="composer1 example" width="300px" apply="com.ui.MyComposer3" border="normal">
<grid>
<rows>
<row>First name : <textbox id="fname" forward="onChange=onFirstName"/></row>
<row>Second name : <textbox id="sname" forward="onChange=onSecondName"/></row>
<row>Full name : <label id="fullname"/></row>
</rows>
</grid>
</window>
</zk>
例1:com.ui.MyComposer.java:
public class MyComposer implements Composer{ //实现Composer接口
private Textbox firstname;
private Textbox secondname;
private Label fullname;
public void doAfterCompose(Component win) throws Exception {
firstname = (Textbox) win.getFellow("fname"); //页面的数据通过getFellow获得
secondname = (Textbox) win.getFellow("sname");
fullname = (Label) win.getFellow("fullname");
//定义并注册事件监听器
win.addEventListener("onFirstName", new EventListener() {
public void onEvent(Event even) throws Exception {
fullname.setValue(firstname.getValue()+" "+secondname.getValue());
}
});
win.addEventListener("onSecondName", new EventListener() {
public void onEvent(Event arg0) throws Exception {
fullname.setValue(firstname.getValue()+" "+secondname.getValue());
}
});
}
}
例2: com.ui.MyComposer1.java:
相对于MyComposer 来说, MyComposer1 的代码更具有可读性,它将监听器作为独立的方法从doAfterCompose方法中分离出来,但其执行的效果是相同的。这是因为MyCompser1 继承了 GenericComposer 类。
public class MyComposer1 extends GenericComposer { //继承GenericComposer 类
private Textbox firstname;
private Textbox secondname;
private Label fullname;
public void doAfterCompose(Component win) throws Exception {
super.doAfterCompose(win);
firstname = (Textbox) win.getFellow("fname");
secondname = (Textbox) win.getFellow("sname");
fullname = (Label) win.getFellow("fullname");
//添加 addEventListener(remove 到该方法外)
}
public void onFirstName(Event event){
fullname.setValue(firstname.getValue()+" "+ secondname.getValue());
}
public void onSecondName(Event event){
fullname.setValue(firstname.getValue()+" "+ secondname.getValue());
}
}
例3:com.ui.MyComposer2.java:
例3相比例2来说,代码更为简洁。它通过继承GenericAutowireComposer ,只要属性名与id值相同,就可自动绑定数据而无需调用getFellow方法。
GenericAutowireComposer类中的doAfterCompose 方法会自动帮你注入匹配的值,包括spring的bean类,如下面的例4。
public class MyComposer2 extends GenericAutowireComposer {
private Textbox fname; //auto-wired (属性名要与id标志匹配)
private Textbox sname;
private Label fullname;
//所有的getFellow 都可以省了
public void onFirstName(Event event){
fullname.setValue(fname.getValue()+" "+sname.getValue());
}
public void onSecondName(Event event){
fullname.setValue(fname.getValue()+" "+sname.getValue());
}
}
例4:spring-config.xml 、 taskEditor.zul 、 TaskEditorComposer.java :
...
<bean id="taskDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
...
<window id="taskWnd" title="Task Editor" border="normal" width="500px" apply="TaskEditorComposer">
<grid>
<rows>
<row>Title: <textbox id="title"/></row>
<row>Description: <textbox id="description"/></row>
</rows>
</grid>
<button id="saveBtn" label="Save" forward="onClick=onSaveTask"/>
</window>
public class TaskEditorComposer extends GenericAutowireComposer {
private TransactionProxyFactoryBean taskDao; //Spring bean auto wired
private Textbox title; //auto wired
private Textbox description; //auto wired
private Button saveBtn; //auto wired
public void onSaveTask(Event event) {
Task currentTask = componentScope.get("task");
currentTask.setTitle(title.getValue());
currentTask.setDescription(description.getValue());
taskDao.update(currentTask);
}
...
}
例5是为了说明GenericAutowireComposer 类支持隐式对象,如代码中的“self”。
public class MyComposer3 extends GenericAutowireComposer{
private Textbox fname;
private Textbox sname;
private Label fullname;
public void onFirstName(Event event){
fullname.setValue(fname.getValue()+" "+sname.getValue());
((Window)self).setTitle("First Name Changed ");
alert("First Name Changed to " + fname.getValue());
}
public void onSecondName(Event event){
fullname.setValue(fname.getValue()+" "+sname.getValue());
((Window)self).setTitle("Second Name Changed ");
alert("Second Name Changed to " + sname.getValue());
}
}
例6:ZUL:
例6是例5的另外一种实现方式:将java代码嵌套在ZUL文件中。
<zk>
<window title="composer 1_3 example " border="normal" width="300px">
<attribute name="onFirstName">
<!--[CDATA[
fullname.setValue(fname.getValue()+" "+sname.getValue());
((Window)self).setTitle("First name changed");
alert("First name change to " + fname.getValue());
]]>
</attribute>
<attribute name="onSecondName">
<![CDATA[
fullname.setValue(fname.getValue()+" "+sname.getValue());
((Window)self).setTitle("Second name changed");
alert("Second name change to " + sname.getValue());
]]-->
</attribute>
<grid>
<rows>
<row>First Name : <textbox id="fname" forward="onChange=onFirstName"/></row>
<row>Second Name : <textbox id="sname" forward="onChange=onSecondName"/></row>
<row>Full Name : <label id="fullname"/></row>
</rows>
</grid>
</window>
</zk>
例7:ZUL 、com.ui.MyComposer4.java :
MyComposer4 类继承了 GenericForwardComposer.可以通过监听器的方法名指定监听的组件(以xx$xx的方式),不需要在zul文件中指定 “forward” 属性。
<zk>
<!-- <window title="comp2 example " border="normal" apply="com.ui.MyComposer4" width="500"> -->
<window title="comp2 example " border="normal" apply="com.ui.MyComposer5" width="500">
<grid>
<rows>
<row>First Name:<textbox id="fname"/></row>
<row>Second Name:<textbox id="sname"/></row>
<row>full Name:<label id="fullname"/></row>
</rows>
</grid>
</window>
</zk>
public class MyComposer4 extends GenericForwardComposer{
private Label fullname;
private Textbox fname;
private Textbox sname;
public void onChange$fname(){
fullname.setValue(fname.getValue()+" "+sname.getValue() );
}
public void onChange$sname(){
fullname.setValue(fname.getValue()+" "+sname.getValue());
}
public void onClick$fullname(){
((Window)self).setTitle(" full name OnClick ");
alert("the full name is " + fullname.getValue());
}
}
例8: com.ui. MyComposer5.java :
实际应用中,当你不得不实现其他接口,继承其他的类时,你可以使用以下方式以达到例6的效果。
public class MyComposer5 implements Composer{
private Textbox fname;
private Textbox sname;
private Label fullname;
public void doAfterCompose(Component win) throws Exception {
//绑定变量值
Components.wireVariables(win, this);
//注册onXXX事件监听器
Events.addEventListeners(win, this);
//自动跳转
Components.addForwards(win, this);
}
public void onChange$fname(Event event){
fullname.setValue(fname.getValue()+" "+sname.getValue());
}
public void onChange$sname(Event event){
fullname.setValue(fname.getValue()+" "+sname.getValue());
}
}
当在需要使用use属性的情况下时:
<window title="mywindow example" border="normal" width="300px" use="MyWindow">
<grid>
<rows>
<row>First Name: <textbox id="firstName"/></row>
<row>Last Name: <textbox id="lastName"/></row>
<row>Full Name: <label id="fullName"/></row>
</rows>
</grid>
</window>
public class MyComposer6 extends Window implements AfterCompose{
private Textbox fname;
private Textbox sname;
private Label fullname;
public void afterCompose() {
//绑定属性值
Components.wireVariables(this, this);
//此时 不需要注册事件监听器
//指定自动跳转
Components.addForwards(this, this);
}
public void onChange$fname(Event event){
fullname.setValue(fname.getValue()+" "+ sname.getValue());
}
public void onChange$sname(Event event){
fullname.setValue(fullname.getValue()+" "+ sname.getValue());
}
}