<h:selectonemenu>为所有下拉列表调用的值更改侦听器而不是仅当前</h:selectonemenu>

时间:2013-07-13 12:56:42

标签: jsf selectonemenu valuechangelistener

我正在使用MyFaces 1.1。我有两个<h:selectOneMenu>个下拉列表,每个下拉列表都指向相同的valueChangeListener方法。

<h:selectOneMenu id="d1" value="#{mybean.selectedChannel1}" 
    onchange="submit()" valueChangeListener="#{myform.channelValuechange}">
    <f:selectItems value="#{mybean.channelList}"/>
</h:selectOneMenu>

<h:selectOneMenu id="d2" value="#{mybean.selectedChannel2}"
    onchange="submit()" valueChangeListener="#{myform.channelValuechange}">
    <f:selectItems value="#{mybean.channelList}"/>
</h:selectOneMenu>

当我更改第一个下拉列表时,值更改侦听器方法会被正确触发。在方法中,我通过sourceId参数获取当前组件的ID为ValueChangeEvent,然后将其比较如下:

if (sourceId.equals("d1")) {
    // ...
} else if (sourceId.equals("d2")) {
    // ...
}

但是,我的具体问题是d2更改后也会调用d1块。

我尝试了这一个,并认为以下有助于解决问题:

if (!event.getPhaseId().equals(PhaseId.INVOKE_APPLICATION)) {
      event.setPhaseId(PhaseId.INVOKE_APPLICATION);
      event.queue();
}

但是,我觉得这不是最好的解决方案。这是如何引起的,如何在不使用上述代码的情况下解决它?

1 个答案:

答案 0 :(得分:3)

使用onchange="submit()",您基本上在更改当前输入元素时提交整个表单,而不仅仅是当前更改的输入!与许多初学者错误思考的相反,这里没有任何特定于输入的JavaScript / Ajax魔法。当您提交整个表单时,它将触发所有输入组件的处理。

当输入组件的提交值不像支持bean中那样valueChangeListener初始模型值时,equals() 始终被调用。鉴于在您的情况下,当您仅更改第一个菜单时,两个菜单都会触及值更改侦听器,这只能意味着第二个菜单的默认选择项值不会equals()支持bean中的初始模型值。

您需要确保第二个菜单的#{mybean.selectedChannel2}默认完全与第二个菜单列表的#{mybean.channelList}的第一项相同。这样,当您更改第一个菜单时,不会为第二个菜单调用值更改侦听器。

另见: