AjaxAction事件是对动作事件的扩展和补充。请考虑这样的情景:当w:dataGrid的某个格子被选中时,我们希望知道用户选取了哪个格子并进行相应的处理,这个需求用前面几种事件是无法直接解决的。而AjaxAction事件则能很好地解决这类问题。我们可以为构件添加客户端事件监听器,当构件产生相应客户端事件时,发送一个Ajax请求到后台调用指定的服务器方法。OperaMasks中有一个专门的构件用来满足此类需求,如下
<w:form>
<w:dataGrid id="grid" selectionModel="new org.operamasks.faces.component.grid.CellSelectionModel()">
<ajax:action event="oncellselect" action="#{bean.doCellSelect }"></ajax:action>
</w:dataGrid>
</w:form>那么,当dataGrid的CellSelect事件发生时,就会调用后台bean的doCellSelect方法。OperaMasks还提供了IoVC方式为构件添加AjaxAction,详细请参看第 20 章 IoVC一节。从OperaMasks2.3版本开始,对AjaxAction事件处理机制做了扩展,所有的AjaxAction都支持无form提交。如果触发事件的构件实现了AjaxActionSupport接口,那么AjaxAction事件的处理有以下特性
AjaxAction构件的action属性指定的方法签名具备多样性特征,可以根据事件名称及方法签名找到一个最合适的方法在广播事件时执行,如果页面如下
<w:textField>
<ajax:action event="onchange" action="#{demoBean.txt_onchange}"/>
</w:textField>那么广播事件时根据方法名称及事件名,将在demoBean中先查找签名为txt_onchange(FieldChangeEvent e)的方法,如存在即执行,否则继续查找签名为txt_onchange(AjaxActionEvent e)的方法,如存在即执行,否则继续查找签名为txt_onchange()的方法,如存在即执行,否则抛出找不到指定方法的异常。demoBean如下
public void txt_onchange(FieldChangeEvent event) {
// do something here
}
public void txt_onchange(AjaxActionEvent event) {
// do some thing here
}
public void txt_onchange() {
// do some thing here
}根据最佳匹配原则,将会执行 "public void txt_onchange(FieldChangeEvent event)"方法。
可以从AjaxActionEvent及其子类这个参数中直接取得与事件相关的参数。AjaxActionEvent类有几个常用的方法
/** * 获得触发事件的构件 */ public UIComponent getTargetComponent(); /** * 可获得通过 ajax:param 构件传递的参数及强类型参数 */ public Map<String, Object> getParamsMap(); /** * getParamsMap().get(String parameter) 的便捷用法 */ public Object getParameter(String parameter);
OperaMasks提供了一些常用的强类型事件,每个强类型事件都有一些与事件相关的参数。如上面的例子,便可从 FieldChangeEvent 里面获取"oldValue"和"newValue"
public void txt_onchange(FieldChangeEvent event) {
System.out.println(event.getOldValue());
System.out.println(event.getNewValue());
}用户可动态添加事件监听器,如下
@Bind
private UITextField txt;
public void txt_onchange(AjaxActionEvent e){
// do some thing here
}
@BeforeRender
public void beforeRender(boolean isPostback){
if(!isPostback){
txt.getAjaxEventHandler().addELBinding("onchange", "#{testBean.txt_onchange}", false);
}
}用户可传递自己的参数。为了便于用户在提交Ajax请求的时候传递自己的参数,从2.3版本开始提供了一个构件<ajax:param>可用来传递参数
<w:textField>
<ajax:action event="onblur" action="#{bean.action}">
<ajax:param name="#{bean.paramName}" value="APUSIC" isJsExpression="false"></ajax:param>
</ajax:action>
</w:textField>isJsExpression属性如果为true(默认为false),那么传递的是JavaScript变量值,此时value属性将首先在客户端求值再进行传递,因此它必须是合法的JavaScript表达式。
<w:textField jsvar="txt">
<ajax:action event="onblur" action="#{bean.action}">
<ajax:param name="#{bean.paramName}" value="txt.getValue()" isJsExpression="true"></ajax:param>
</ajax:action>
</w:textField>在这儿我们将w:textField的值传递到服务器端, bean可获取此值, 如下
@ManagedProperty
private String paramName = "paramName";
public void action(AjaxActionEvent event) {
System.out.println(event.getParameter(paramName));
}当然,获取出来的值都是String型。同时要求传递的JavaScript变量是基本类型或者String类的实例。
下表是实现了AjaxActionSupport接口的构件和对应的一些强类型事件。
表 18.1. 实现AjaxActionSupport接口的构件
| 实现AjaxActionSupport接口的构件 | 构件支持的客户端事件 | 构件支持的强类型事件类 |
| w:dataGrid | onselectionchange, onrowselect, onrowdeselect, ondblclick, oncellselect | RowSelectEvent, RowDeselectEvent, RowDblClick, CellSelectEvent |
| w:editDataGrid | onselectionchange, onrowselect, onrowdeselect, ondblclick, oncellselect | RowSelectEvent, RowDeselectEvent, RowDblClick, CellSelectEvent |
| w:tree | onclick, oncheck, oncollapsenode, onexpandnode, onselect | TreeNodeEvent(所有事件都可用此事件类) |
| w:textField | onfocus, onblur, onkeyup, onkeydown, onkeypress, onchange, ondisable, onenable, onshow, onhide | FieldChangeEvent(对应onchange事件) |
| w:checkBox | onfocus, onblur, onkeyup, onkeydown, onkeypress, onchange, ondisable, onenable, onshow, onhide, oncheck | FieldChangeEvent(对应onchange事件),CheckEvent(对应oncheck事件) |
| w:calcNumberField | onfocus, onblur, onkeyup, onkeydown, onkeypress, onchange, ondisable, onenable, onshow, onhide | FieldChangeEvent(对应onchange事件) |
| w:numberField | onfocus, onblur, onkeyup, onkeydown, onkeypress, onchange, ondisable, onenable, onshow, onhide | FieldChangeEvent(对应onchange事件) |
| w:textArea | onfocus, onblur, onchange, ondisable, onenable, onshow, onhide | FieldChangeEvent(对应onchange事件) |
| w:combo | onfocus, onblur, onchange, ondisable, onenable, onshow, onhide,onexpand,oncollapse,onselect | FieldChangeEvent(对应onchange事件),SelectionChangedEvent(对应onselect事件) |
| w:timeField | onfocus, onblur, onchange, ondisable, onenable, onshow, onhide,onexpand,oncollapse,onselect | FieldChangeEvent(对应onchange事件),SelectionChangedEvent(对应onselect事件) |
| w:dateField | onfocus, onblur, onchange, ondisable, onenable, onshow, onhide | FieldChangeEvent(对应onchange事件) |
| w:dateTimeField | onfocus, onblur, onchange, ondisable, onenable, onshow, onhide | FieldChangeEvent(对应onchange事件) |
下面是强类型事件具有的属性列表。
表 18.2. 强类型事件及其属性
| 强类型事件类 | 属性 |
| FieldChangeEvent | oldValue, newValue |
| CheckEvent | checked |
| SelectionChangedEvent | label, index, value |
| RowSelectEvent | rowIndex, selectedValues |
| RowDeselectEvent | rowIndex |
| RowDblClickEvent | rowIndex, selectedValues |
| CellSelectEvent | rowIndex, colIndex, selectedValues |
| TreeNodeEvent | eventNode |
| KeyEvent | shiftKey, ctrlKey, altKey, key |