Valuechangelistener在JSF中存在疑问

时间:2011-01-26 05:01:43

标签: jsf

HI,

请参阅以下代码:

                <h:selectOneMenu id="countries" value="#{countryBean.selectedCountry}" onchange="submit()
                                    valueChangeListener="#{countryBean.changeCountry}">
                    <f:selectItems value="#{countryBean.countries }" />
                </h:selectOneMenu>  

支持Bean

public void changeCountry(ValueChangeEvent event){      
    String newValue = (String)event.getNewValue();
    String oldValue = (String)event.getOldValue();

    System.out.println("New Value : " + newValue);
    System.out.println("Old Value : " + oldValue);

    if ("1".equals(newValue)){
        this.countries = new ArrayList<SelectItem>();
        this.cities.add(new SelectItem("1","Delhi"));
        this.cities.add(new SelectItem("2","Mumbai"));
    }
    if ("2".equals(newValue)){
        this.cities = new ArrayList<SelectItem>();
        this.cities.add(new SelectItem("1","Mossco"));
    }       
}

如果实施正确,请告诉我。它工作正常。 我的问题是:

  • h:selectOneMenu 标记内添加 f:valueChangeListener 标记有什么好处。我使用了普通属性valueChangeListener =“#{countryBean.changeCountry}”。
  • 是否有必要使用 onchange =“submit()此代码来更改值。
  • 通过实现ActionListener接口并仅使用UIComponent标记中的属性(action =“methodName”)来编写自定义侦听器之间有什么区别。 请解释一下。

3 个答案:

答案 0 :(得分:20)

ValueChangeListener仅在提交表单时调用,而不是在输入值更改时调用。因此,如果要在修改值时运行此侦听器,则有两个解决方案:

  1. onchange事件被触发时提交您的表单(这是您在代码中所做的);
  2. 使用Ajax调用,使用一些专用组件(已集成在JSF2中,<f:ajax>或第三方库,如Richfaces,Primefaces ......)。
  3. 以下是Richfaces的示例:

    <h:selectOneMenu id="countries" value="#{countryBean.selectedCountry}" valueChangeListener="#{countryBean.changeCountry}">
        <a4j:support event="onchange" .../>
        <f:selectItems value="#{countryBean.countries }" />
    </h:selectOneMenu>
    

    关于你的监听器的代码,它似乎是正确的,但为什么为什么你需要一个ValueChangeListener ?实际上,当您想要跟踪值的修改时,此侦听器很有用。这就是ValueChangeEvent同时提供getOldValue()getNewValue()方法的原因。

    在您的代码中,您不关心旧值,所以基本上,您可以“简单地”执行操作而不是valueChangeListener(例如Richfaces):

    <h:selectOneMenu id="countries" value="#{countryBean.selectedCountry}">
        <a4j:support event="onchange" actionListener="#{countryBean.changeCountry}"/>
        <f:selectItems value="#{countryBean.countries }" />
    </h:selectOneMenu>
    

    最后,关于valueChangeListener属性和<f:valueChangeListener>之间的区别在于第一个绑定Java方法(#{myBean.myMethod}),而第二个绑定Java类(type="com.foo.MyListenerClass" })实现ValueChangeListener接口。所以第二个可能比第一个更通用......

答案 1 :(得分:6)

Romaintaz已经指出了最多,我只是想直截了当地提出你的具体问题:

  

在h:selectOneMenu标记内添加f:valueChangeListener标记有什么好处。我使用了普通属性valueChangeListener =“#{countryBean.changeCountry}”。

正如Romaintaz所说,该属性指向一个方法,f:标记指向一个类。另一个优点是,只要有必要,您就可以拥有多个。

  

是否有必要使用onchange =“submit()此代码来更改值。

Javascript不会更改值。只要最终用户更改了值,Javascript就会提交整个表单而无需自己按下提交按钮。不,这不是必要的。您也可以删除它并期望最终用户自己按下提交按钮。 Once again,JavaScript不是JSF的一部分。

  

通过实现ActionListener接口并仅使用UIComponent标记中的属性(action =“methodName”)来编写自定义侦听器之间的区别是什么。

之前已经问过这个问题:difference between action and actionlistener

答案 2 :(得分:0)

romaintaz调用action而不是valueChangeListener的解决方案也很棒,因为在“change”事件的情况下,在更新模型之后调用操作(例如允许数据库更新),而之前调用valueChangeListener ....