Поверхность valueChangeListener или <p: прослушиватель ajax не запускается для p: selectOneMenu
Я использую Primfaces 3.4.2.
У меня на странице JSF есть следующее:
<p:selectOneMenu id="emp" value="#{mymb.emp.employeeName}"
valueChangeListener="#{mymb.handleChange}"
required="true"
style="width: 150px;">
<f:selectItem noSelectionOption="true"
itemLabel="Please Select"/>
<f:selectItems value="#{mymb.employeeList}" var="emp"
itemLabel="#{emp.employeeName}" itemValue="#
{emp.employeeNumber}"/>
<p:ajax update="sublist" />
</p:selectOneMenu>
и в ManagedBean
public void handleChange(ValueChangeEvent event){
System.out.println("here "+event.getNewValue());
}
Проблема valueChangeListener
не запускается, т.е. метод handleChange
не запускается. Я пробовал со следующим, но он тоже не работает.
<p:ajax update="sublist"
listener="#{mymb.handleChange}" />
Как я могу решить эту проблему?
Спасибо
Обновление 1
<ui:composition template="/templates/layout.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<ui:define name="content">
<h:head>
</h:head>
<h:body>
<h:form id="form">
<p:panelGrid columns="6">
<h:outputLabel value="Employees" for="employees" />
<p:selectOneMenu id="employees" value="#{mymb.employeesList}"
required="true">
<f:selectItems value="#{mymb.employeesList}" var="emp"
itemLabel="#{emp.employeeName}" />
<p:ajax listener="#{mymb.handleChange}" />
</p:selectOneMenu>
</p:panelGrid>
</h:form>
</h:body>
</ui:define>
</ui:composition>
Ответы
Ответ 1
Если вы хотите использовать valueChangeListener
, вам необходимо отправить форму каждый раз, когда будет выбран новый вариант. Что-то вроде этого:
<p:selectOneMenu value="#{mymb.employee}" onchange="submit()"
valueChangeListener="#{mymb.handleChange}" >
<f:selectItems value="#{mymb.employeesList}" var="emp"
itemLabel="#{emp.employeeName}" itemValue="#{emp.employeeID}" />
</p:selectOneMenu>
public void handleChange(ValueChangeEvent event){
System.out.println("New value: " + event.getNewValue());
}
Или, если вы хотите использовать <p:ajax>
, он должен выглядеть следующим образом:
<p:selectOneMenu value="#{mymb.employee}" >
<p:ajax listener="#{mymb.handleChange}" />
<f:selectItems value="#{mymb.employeesList}" var="emp"
itemLabel="#{emp.employeeName}" itemValue="#{emp.employeeID}" />
</p:selectOneMenu>
private String employeeID;
public void handleChange(){
System.out.println("New value: " + employee);
}
Следует отметить, что в вашем примере кода я заметил, что атрибут value
вашего <p:selectOneMenu>
равен #{mymb.employeesList}
, который совпадает с value
от <f:selectItems>
. value
вашего <p:selectOneMenu>
должен быть похож на мои примеры выше, которые указывают на одного сотрудника, а не на список сотрудников.
Ответ 2
valueChangeListener
нужен только, если вас интересует как старое, так и новое значение.
Если вас интересует только новое значение, лучше использовать <p:ajax>
или <f:ajax>
.
Существует несколько возможных причин, почему вызов ajax не будет работать. Сначала вы должны изменить сигнатуру метода метода обработчика: отбросьте параметр. Затем вы можете напрямую получить доступ к своей управляемой переменной bean:
public void handleChange(){
System.out.println("here "+ getEmp().getEmployeeName());
}
В то время, когда вызывается слушатель, новое значение уже установлено. (Заметим, что я неявно предполагаю, что выражение el mymb.emp.employeeName
правильно поддерживается соответствующими методами getter/setter.)
Ответ 3
<p:ajax listener="#{my.handleChange}" update="id of component that need to be rerender after change" process="@this" />
import javax.faces.component.UIOutput;
import javax.faces.event.AjaxBehaviorEvent;
public void handleChange(AjaxBehaviorEvent vce){
String name= (String) ((UIOutput) vce.getSource()).getValue();
}
Ответ 4
Другим решением является сочетание valueChangeListener, ajax и процесса:
<p:selectManyCheckbox id="employees" value="#{employees}" columns="1" layout="grid" valueChangeListener="#{mybean.fireSelection}" >
<f:selectItems var="employee" value="#{employeesSI}" />
<p:ajax event="valueChange" immediate="true" process="@this"/>
</p:selectManyCheckbox>
Метод в mybean справедлив:
public void fireSelection(ValueChangeEvent event) {
log.debug("New: "+event.getNewValue()+", Old: "+event.getOldValue());
}
Подобно этому, valueChangeEvent очень легкий!
PS: отлично работает с PrimeFaces 5.0
Ответ 5
Все может быть определено как в f:ajax
attiributes.
то есть.
<p:selectOneMenu id="employees" value="#{mymb.employeesList}" required="true">
<f:selectItems value="#{mymb.employeesList}" var="emp" itemLabel="#{emp.employeeName}" />
<f:ajax event="valueChange" listener="#{mymb.handleChange}" execute="@this" render="@all" />
</p:selectOneMenu>
событие: это могут быть обычные события DOM, такие как click
или valueChange
выполнить. Это список разделенных пробелами идентификаторов клиентов компонентов, которые будут участвовать в части "выполнения" жизненного цикла обработки запросов.
render: клиентские компоненты компонентов, которые будут участвовать в части "рендеринга" жизненного цикла обработки запросов. После выполнения действий вы можете определить, какие компоненты должны обновляться. Id, IdList или эти ключевые слова могут быть добавлены: @this
, @form
, @all
, @none
.
Вы можете обновить весь список атрибутов по следующей ссылке:
http://docs.oracle.com/javaee/6/javaserverfaces/2.1/docs/vdldocs/facelets/f/ajax.html
Ответ 6
Попробуйте использовать p: ajax с атрибутом события,
Ответ 7
Моя проблема заключалась в том, что мы использовали spring securyty, а предыдущая страница не вызывала страницу с помощью faces-redirect = true, тогда на странице отображается предупреждение java, и элемент управления не запускает событие изменения,
Решение:
Предыдущая страница должна вызывать страницу с помощью: faces-redirect = true
Ответ 8
это работает для меня:
Его можно использовать внутри диалогового окна, но диалог не может находиться внутри любого компонента, такого как панели, аккордеон и т.д.