#java #jsf #jsf-2 #valuechangelistener
#java #jsf #jsf-2 #valuechangelistener
Вопрос:
Это мой код в моем управляемом компоненте :-
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<center>
<h:form>
<h2> <u>Select Fruit(s). </u> </h2>
<!-- Value Change Listener is entirely superflous. You can make a full blown project without requiring the need to ever use this...This is
just for demo purpose..-->
<h:selectManyMenu onchange="document.forms[0].submit();" style="height: 200px;font-size: 1.5em;width: 200px;" >
<f:selectItems value="#{actionValueLisBean.fruitsList}" var="fruit" itemLabel="#{fruit}" itemValue="#{fruit}"/>
<f:valueChangeListener type="beans.ActionValueLisBean"/>
</h:selectManyMenu>
<h3> Your previous selection is :<h:outputText value="#{actionValueLisBean.prevSel}"/></h3>
<h3>Your current selection is :<h:outputText value="#{actionValueLisBean.currSel}"/></h3>
</h:form>
</center>
</h:body>
</html>
Это мой компонент :-
package beans;
import com.sun.jmx.remote.internal.ArrayQueue;
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ValueChangeEvent;
import javax.faces.event.ValueChangeListener;
@ManagedBean
@RequestScoped
public class ActionValueLisBean implements ValueChangeListener {
private List<String> fruitsList;
private String currSel;
private String prevSel;
public String getCurrSel() {
return currSel;
}
public void setCurrSel(String currSel) {
this.currSel = currSel;
}
public String getPrevSel() {
return prevSel;
}
public void setPrevSel(String prevSel) {
this.prevSel = prevSel;
}
public List<String> getFruitsList() {
return fruitsList;
}
public void setFruitsList(List<String> fruitsList) {
this.fruitsList = fruitsList;
}
public ActionValueLisBean() {
fruitsList = new ArrayQueue<String>(5);
fruitsList.add("Apple");
fruitsList.add("Mango");
fruitsList.add("Banana");
fruitsList.add("Peach");
fruitsList.add("Plum");
}
@Override
public void processValueChange(ValueChangeEvent event) throws AbortProcessingException {
if(event.getOldValue() != null)
prevSel = event.getOldValue().toString();
if(event.getNewValue() != null)
currSel = "abc";
}
}
И тогда у меня есть prevSel, а currSel привязан к h:outputText
. Но значение не передается, даже несмотря на то, что processValueChange запущен правильно и System.out.println(event.getNewValue());
также работает нормально. Я тоже пробовал устанавливать разные области bean, но бесполезно. Я знаю, что valueChangeListener совершенно бесполезен. Тем не менее, я хочу знать, как это работает.
Заранее спасибо 🙂
Ответ №1:
Я не уверен, что вы имеете в виду, говоря «значение не получает». Вам следует уточнить это немного подробнее.
По крайней мере, его единственная цель — прослушивать изменение значения, чтобы вы могли выполнять некоторые бизнес-действия на основе изменения, такие как ведение журнала или предварительная загрузка некоторых данных, связанных с новым значением. Когда начальное значение равно отправленному значению, этот метод вызываться не будет.
Вот фрагмент кода, с которым можно поиграть самостоятельно:
<h:form>
<p>Input value: <h:inputText value="#{bean.value}" valueChangeListener="#{bean.change}"/></p>
<p>Old value: <h:outputText value="#{bean.oldValue}" /></p>
<p>New value: <h:outputText value="#{bean.newValue}" /></p>
<p><h:commandButton value="submit" action="#{bean.submit}" /></p>
</h:form>
Компонент:
package com.example;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ValueChangeEvent;
@ManagedBean
@ViewScoped
public class Bean {
private String value;
private String oldValue;
private String newValue;
public void submit() {
System.out.println("Submit: " value);
}
public void change(ValueChangeEvent event) {
oldValue = (String) event.getOldValue();
newValue = (String) event.getNewValue();
System.out.println("Change: " oldValue " to " newValue);
}
public String getValue() {
return value;
}
public String getOldValue() {
return oldValue;
}
public String getNewValue() {
return newValue;
}
public void setValue(String value) {
this.value = value;
}
}
Обновление: согласно вашему обновлению: вы используете два разных экземпляра компонента. На самом деле вы отображаете значения управляемого компонента, а не того компонента, который был недавно создан f:valueChangeListener
.
Комментарии:
1. Привет, БалусК, пожалуйста, прочтите мой отредактированный пост. Я не использую valuelistener компонента. Я использую
f:valueListener
. Можете ли вы найти ошибку в моем коде? Я читаю эту статью :- java-server-faces.blogspot.com/2006/04 /… Но это не работает 🙁2. Смотрите обновление. Чтобы устранить эту проблему, продолжайте использовать предложенный мной подход.
3. Привет, БалусК, я так ничего и не понял. Итак, что я должен делать дальше?
4.
f:valueChangeListener
Создается новый экземпляр компонента. Он не использует тот же экземпляр, что и отображаемые компоненты ввода / вывода. Теперь у вас есть два компонента, и вы отображаете значения из «неправильного» компонента. Используйте мой подход для достижения требования, которое вы изначально имели в виду. Используйте свой подход, чтобы полностью отключить прослушивание событий изменения от управляемого компонента (и вы не заинтересованы в доступе к компоненту прослушивателя изменения значения в представлении).5. Отлично! Спасибо BalusC. Кстати, ваши баллы значительно выросли! В последний раз, когда я использовал JSF 2.0 в июне, они составляли 54,4 тыс. Сейчас их 82,8 тыс. Таким образом, вы даже побьете рекорд Джона Скита.