Сопротивление Valuechangelistener в 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"));
    }       
}

Пожалуйста, дайте мне знать, правильна ли реализация. Он работает нормально. Мои вопросы:

  • В чем преимущество добавления тега f: valueChangeListener внутри тега h: selectOneMenu. Я использовал обычный атрибут valueChangeListener = "# {countryBean.changeCountry}".
  • Нужно ли использовать onchange = "submit() этот код для изменения значений.
  • В чем разница между написанием пользовательских слушателей путем реализации интерфейса ActionListener и просто использованием атрибута в тегах UIComponent (action = "methodName" ). Пожалуйста, объясните мне.

Ответы

Ответ 1

ValueChangeListener будет вызываться только при отправке формы, а не при изменении значения ввода. Таким образом, если вы хотите запустить этот прослушиватель, когда значение изменено, у вас есть два решения:

  • Отправьте свою форму при запуске события onchange (это то, что вы сделали в своем коде);
  • Вместо этого используйте вызов Ajax, используя некоторые выделенные компоненты (уже интегрированные в JSF2, с <f:ajax> или сторонними библиотеками, такими как Richfaces, Primefaces...).

Вот пример с 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 интерфейс. Таким образом, второй может быть более общим, чем первый...

Ответ 2

Роменцаз уже указывал больше всего, я просто хотел получить прямо на ваши конкретные вопросы:

В чем преимущество добавления тега f: valueChangeListener внутри тега h: selectOneMenu. Я использовал обычный атрибут valueChangeListener = "# {countryBean.changeCountry}".

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

Нужно ли использовать onchange = "submit() этот код для изменения значений.

Этот Javascript не меняет значения. Этот Javascript представляет всю форму без необходимости нажимать кнопку отправки самостоятельно, всякий раз, когда значение было изменено конечным пользователем. Нет, это не обязательно. Вы также можете просто удалить его и ожидать, что конечный пользователь сам нажмет кнопку отправки. Еще раз, что JavaScript не является частью JSF.

В чем разница между написанием пользовательских слушателей путем реализации интерфейса ActionListener и просто использованием атрибута в тегах UIComponent (action = "methodName" ).

Этот вопрос уже задан раньше: разница между действием и actionlistener.

Ответ 3

Решение от romaintaz вызова действия вместо valueChangeListener также отлично, потому что в случае события "change" действие вызывается после обновления модели (например, для обновления базы данных), а valueChangeListener вызывается перед....