(如何)可以通过 AjaxBeahviorEvent 获取 UIInput 的值以获取已更改的 inputText
(How) Can one obtain the value of a UIInput via an AjaxBeahviorEvent for a changed inputText
为了一个看似简单的案例,我已经苦思冥想了一段时间。我有一个 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>
部分似乎有效。
所以我的问题(或可能是问题)是,我是否有可能通过 AjaxBehaviorEvent 读取控制器中 InputText 的新输入值,或者我是否必须尝试其他方法(可能设置inputText 的值到 f:param)?还检查了我在服务器端的 requestMap 中也没有找到任何值...
我还检查了 Chrome 检查员通过 ajax 请求发布的内容。我没有找到任何证据表明我在 <p:inputText>
中输入的文本会被发送到服务器。
任何人都可以启发或给我一些关于这个问题的指示吗?
编辑:
正如 @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!
}
即使现在的程序非常小,输入文本的值似乎也没有发送到服务器端。在我看来,一件奇怪的事情是我需要那些 h:form-tags 才能让示例触发 ajax 请求。
这是当我将 TestingTesting 提供给输入文本并按回车键(使用 Chrome Inspector)时 xhr POST 请求参数的样子:
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;
对我来说,问题的实际解决方案是将我的 table 包装在一个表单中。如果没有在某种程度上包装它的表单标签,ajax 标签将不起作用。
这是我的完整示例。无论我在 "hello" 之类的输入文本中输入什么,都会在 System.out.println.
中出现
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>PrimeFaces Test</title>
</h:head>
<h:body>
<h:form id="frmTest">
<p:inputText id="inpresx" value="#{testView.testString}" >
<p:ajax event="change" process="@this" listener="#{testView.doStuff}" />
</p:inputText>
</h:form>
</h:body>
</html>
Java:
package org.primefaces.test;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.component.UIInput;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ManagedBean(name = "testView")
@ViewScoped
public class TestView implements Serializable {
private String testString;
public void doStuff(AjaxBehaviorEvent e) {
Object val = ((UIInput)e.getSource()).getValue();
System.out.println("Value = " + val);
}
public String getTestString() {
return testString;
}
public void setTestString(String testString) {
this.testString = testString;
}
}
我的 Chrome 输出:
javax.faces.partial.ajax: true
javax.faces.source: frmTest:inpresx
javax.faces.partial.execute: frmTest:inpresx
javax.faces.behavior.event: change
javax.faces.partial.event: change
frmTest: frmTest
frmTest:inpresx: Whosebug
javax.faces.ViewState: 9209410033241115450:-5298602114910206430
为了一个看似简单的案例,我已经苦思冥想了一段时间。我有一个 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>
部分似乎有效。
所以我的问题(或可能是问题)是,我是否有可能通过 AjaxBehaviorEvent 读取控制器中 InputText 的新输入值,或者我是否必须尝试其他方法(可能设置inputText 的值到 f:param)?还检查了我在服务器端的 requestMap 中也没有找到任何值...
我还检查了 Chrome 检查员通过 ajax 请求发布的内容。我没有找到任何证据表明我在 <p:inputText>
中输入的文本会被发送到服务器。
任何人都可以启发或给我一些关于这个问题的指示吗?
编辑:
正如 @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!
}
即使现在的程序非常小,输入文本的值似乎也没有发送到服务器端。在我看来,一件奇怪的事情是我需要那些 h:form-tags 才能让示例触发 ajax 请求。
这是当我将 TestingTesting 提供给输入文本并按回车键(使用 Chrome Inspector)时 xhr POST 请求参数的样子:
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; 对我来说,问题的实际解决方案是将我的 table 包装在一个表单中。如果没有在某种程度上包装它的表单标签,ajax 标签将不起作用。
这是我的完整示例。无论我在 "hello" 之类的输入文本中输入什么,都会在 System.out.println.
中出现<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>PrimeFaces Test</title>
</h:head>
<h:body>
<h:form id="frmTest">
<p:inputText id="inpresx" value="#{testView.testString}" >
<p:ajax event="change" process="@this" listener="#{testView.doStuff}" />
</p:inputText>
</h:form>
</h:body>
</html>
Java:
package org.primefaces.test;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.component.UIInput;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ManagedBean(name = "testView")
@ViewScoped
public class TestView implements Serializable {
private String testString;
public void doStuff(AjaxBehaviorEvent e) {
Object val = ((UIInput)e.getSource()).getValue();
System.out.println("Value = " + val);
}
public String getTestString() {
return testString;
}
public void setTestString(String testString) {
this.testString = testString;
}
}
我的 Chrome 输出:
javax.faces.partial.ajax: true
javax.faces.source: frmTest:inpresx
javax.faces.partial.execute: frmTest:inpresx
javax.faces.behavior.event: change
javax.faces.partial.event: change
frmTest: frmTest
frmTest:inpresx: Whosebug
javax.faces.ViewState: 9209410033241115450:-5298602114910206430