18.2. 值改变事件

当构件值发生变化的时候,值变化事件由输入构件触发——例如w:textField和w:combo(这些构件实现了ValueHolder或EditableValueHolder)。我们有时需要根据构件的值做一些不同的事情,例如

<w:form>
    <w:combo valueChangeListener="#{bean.countryChanged}" onchange="submit();">
        <f:selectItem itemLabel="USA" itemValue="USA" />
        <f:selectItem itemLabel="Canada" itemValue="Canada" />
    </w:combo>
</w:form>

当用户从菜单中选择国家时,会调用JavaScript的submit函数来提交表单进入生命周期。在处理验证阶段末尾,框架会调用LiteBean的countryChanged方法进行处理

public void countryChanged(ValueChangeEvent event) {
     FacesContext context = FacesContext.getCurrentInstance();
     if ("USA".equals((String)event.getNewValue()))
         context.getViewRoot().setLocale(Locale.US);
     else 
         context.getViewRoot().setLocale(Locale.Canada);
}

ValueChangeEvent继承自FacesEvent,其最常用的方法如下

/**
 * 返回触发事件的输入构件
 */
public UIComponent getComponent();

/**
 * 在值被转换和校验后,返回构件的新值
 */
public Object getNewValue();

/**
 * 返回构件的前一个值
 */
public Object getOldValue();

与动作事件类似的,构件同样可以通过设置immediate属性为true让值改变事件监听器提前执行,如果设置immediate属性为true,那么值改变事件监听器将在应用请求值阶段末尾得到调用。