Я уже некоторое время стучу головой по кажущемуся простому делу. У меня есть Primefaces <p:inputText>
(как ячейка внутри <p:dataTable>
), для которой, когда значение изменяется, я хотел бы получить значение в моем контроллере.
Я не могу раскрыть настоящий код, только показывая его жизненно важные выдержки:
<p:column headerText="Ratkaisu">
<p:inputText name="inpres" id="inpres" value="#{entity.resolution}">
<p:ajax event="change" immediate="true" execute="@this inpres" render="@this" listener="#{mainViewController.updateEntity}"/>
<f:param value="#{entity}" name="entity"/>
</p:inputText>
</p:column>
"backing bean" - это мой mainViewController, который @ ViewScoped
Метод получения ajax-данных внутри контроллера:
public void updateEntity(AjaxBehaviorEvent e) {
// I can get the entity via the parameter list
Entity entity = (Entity)FacesContext.getCurrentInstance()
.getExternalContext().getRequestMap().get(entity);
// The value below is always null
Object value = ((UIInput)e.getSource()).getValue();
....
}
Каждый раз, когда изменяется текст (ввод фокуса из текстового поля), я получаю ajax-запрос к своему методу. Каждый раз я нахожу правильную сущность из карты запросов, поэтому <f:param>
-частица, кажется, работает.
Итак, мой вопрос (или, возможно, вопросы) заключается в том, чтобы я мог прочитать вновь введенное значение InputText в контроллере через AjaxBehaviorEvent или мне нужно попробовать что-то другое (возможно, установить значение inputText для f: param)? Также проверил, что я не нашел никаких значений в requestMap на стороне сервера ...
Я также проверил, что Инспектор Chrome публикует через ajax-запросы. Я не нашел никаких доказательств того, что текст, который я ввожу в <p:inputText>
, будет отправлен на сервер.
Может ли кто-нибудь осветить или дать мне несколько советов по этому вопросу?
EDIT:
Как указывалось @ melloware , я сделал пример на стороне клиента как можно более минимальным, все еще полностью работающим:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<f:view>
<h:head>
</h:head>
<h:body>
<h:form id="someid">
</h:form>
<p:inputText id="inpresx">
<p:ajax event="change" process="@this"
listener="#{mainViewController.doStuff}" />
</p:inputText>
</h:body>
</f:view>
</html>
для MainViewController, часть doStuff:
public void doStuff(AjaxBehaviorEvent e) {
Object val = ((UIInput)e.getSource()).getValue();
// val is still null!
}
Даже если программа сейчас очень минимальна, значение для inputtext не передается на серверную часть. Странная вещь IMO, это то, что мне нужны эти h: form-tags для того, чтобы пример запускал ajax-запросы.
Вот как выглядят параметры запроса xhr POST, когда я передаю TestingTesting в текст ввода и нажимаю ввод (с помощью Chrome Inspector):
javax.faces.partial.ajax: true
javax.faces.source: inpresx
javax.faces.partial.execute: inpresx
javax.faces.behavior.event: change
javax.faces.partial.event: change
someid: someid
javax.faces.ViewState: -4351418361364308383:4652862949343904732
Исходя из отправляемых выше данных, похоже, что никакие текстовые данные из входного текста не передаются на серверную сторону. Что я мог сделать не так?
РЕДАКТИРОВАТЬ 2:
tldr;
Фактическим решением проблемы для меня было завернуть мой стол в форму. Тег ajax не будет работать, если нет тега формы, который ОБРАТИТ его на каком-то уровне.