<h:selectOneMenu> value change listener invoked for all dropdowns instead of only the current

限于喜欢 提交于 2019-12-22 11:08:18

问题


I'm using MyFaces 1.1. I have two <h:selectOneMenu>s dropdowns which each point to same valueChangeListener method.

<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>

When I change the first dropdown, then the value change listener method get fired correctly. In the method, I'm obtaining the ID of the current component as sourceId via ValueChangeEvent argument and then comparing it as follows:

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

However, my concrete problem is that d2 block is also called when d1 is changed.

I tried the one and other and figured that the following helped to solve the problem:

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

However, I don't feel like that it's the best solution. How is this caused and how can I solve it without using the above code?


回答1:


With onchange="submit()" you're basically submitting the entire form when the current input element is changed, not only the currently changed input! In contrary to what many starters incorrectly think, there is no means of any input-specific JavaScript/Ajax magic here. As you're submitting the entire form, it would trigger the processing of all input components.

The valueChangeListener is always invoked when the submitted value of the input component does not equals() the initial model value as in the backing bean. Given that in your case both menus hit the value change listener when you change only the first one, that can only mean that the default select item value of the second menu does not equals() the initial model value in the backing bean.

You need to make sure that #{mybean.selectedChannel2} of the second menu has by default exactly the same value as the first item of #{mybean.channelList} of the second menu's list. This way the value change listener won't be invoked for the second menu when you change the first menu.

See also:

  • When to use valueChangeListener or f:ajax listener? (just to learn what's different in JSF 2, for the case you're interested)


来源:https://stackoverflow.com/questions/17630407/hselectonemenu-value-change-listener-invoked-for-all-dropdowns-instead-of-onl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!