Функция события, вызываемая перед сеттером - PullRequest
1 голос
/ 11 октября 2011

У меня есть следующий выпадающий список, в котором перечислены несколько автомобилей, он у меня есть, чтобы он сохранял значение выбранного элемента в переменной бобов, и событие запускается, чтобы другие выпадающие списки заполнялись в соответствии с выбранным значением этого элемента управления.как показано ниже:

  <Td>
<h:selectOneMenu id="combocarList" 
    value="#{customerBean.selectedcar}"
    styleClass="comboStyle"
    valueChangeListener="#{customerBean.loadothercombos}"
    onchange="document.forms[0].submit()"
    >
    <f:selectItem
        itemLabel="-----------Select--------------"
        itemValue="None" />
    <f:selectItems value="#{customerBean.carsList}" />
</h:selectOneMenu>
 </Td>

Проблема заключается в том, что когда элемент, выбранный из раскрывающегося списка, вызывается событие loadothercombos перед сеттером, что вызывает проблемы.

Обратите внимание, что клиент бобов определяется как:

 <managed-bean-name>customerBean</managed-bean-name>
    <managed-bean-class>com.theway.customer</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>

Поведение, которое я вижу при отладке, когда я выбираю элемент из выпадающего списка:

1) Getter is called for selectedcar
2) Loadothercombos is called  <------- This is called by the event
3) Setter is called for selectedcar

Я не могу заставить его вызвать установщик перед вызовом loadothercombos.Любое понимание будет оценено.Спасибо

Ответы [ 2 ]

8 голосов
/ 11 октября 2011

Использование valueChangeListener для этой цели всегда было хакерским способом. По сути, есть два способа обойти эту «проблему»:

  1. Вызовите FacesContext#renderResponse(), чтобы JSF немедленно перешел к фазе ответа рендеринга, и, таким образом, фаза обновления значений модели (и вызова действия) будет пропущена:

    public void loadothercombos(ValueChangeEvent event) {
        selectedcar = (String) event.getNewValue();
        loadOtherCombosBasedOn(selectedcar);
        // ...
    
        FacesContext.getCurrentInstance().renderResponse();
    }
    
  2. Поставить в очередь событие, чтобы вызвать фазу действия, чтобы оно выполняло свою работу после вызова установщика:

    public void loadothercombos(ValueChangeEvent event) {
        if (event.getPhaseId() == PhaseId.INVOKE_APPLICATION) {
            loadOtherCombosBasedOn(selectedcar);
        } else {
            event.setPhaseId(PhaseId.INVOKE_APPLICATION);
            event.queue();
        }
    }
    

Если вы используете JSF 2.0, то есть гораздо более простой способ справиться с этим с помощью <f:ajax>:

<h:selectOneMenu id="combocarList" 
    value="#{customerBean.selectedcar}"
    styleClass="comboStyle">
    <f:selectItem
        itemLabel="-----------Select--------------"
        itemValue="None" />
    <f:selectItems value="#{customerBean.carsList}" />
    <f:ajax listener="#{customerBean.loadOtherCombos}" render="otherComboIds" />
</h:selectOneMenu>

с

public void loadothercombos() {
    loadOtherCombosBasedOn(selectedcar);
}

Не связано с конкретной проблемой: «выпадающий список» - неправильный термин для этого выпадающего элемента. Поле со списком - это редактируемый выпадающий список, в основном это комбинация <input type="text"> и <select>. То, что вы там, просто показывает только <select>, и это просто выпадающие списки, так что называйте их так же.

1 голос
/ 11 октября 2011

Проблема в том, что при выборе элемента из раскрывающегося списка происходит событие loadothercombos вызывается перед сеттером

Ну, это ожидаемое поведение жизненного цикла JSF. Ваш valueChangeListener="#{customerBean.loadothercombos}" вызывается на этапе проверки после успешного преобразования / проверки отправленного значения и только в том случае, если отправленное значение отличается от исходного значения. После вызова valueChangeListener JSF продолжит преобразование / проверку следующего UIInput и, когда реализация JSF определит, что данные действительны, затем перейдет к следующему Update Model Values Phase вызову вашего метода установки value="#{customerBean.selectedcar}"

...