我有一个带有表单的自定义标记文件:
<h:form>
<h:commandButton value="click">
<f:ajax event="click" listener="#{bean[method]}" />
</h:commandButton>
</h:form>
我通过 ajax 有条件地渲染它,如下所示:
<h:panelGroup id="test">
<h:form>
<h:commandButton value="click">
<f:ajax event="click" listener="#{backingTest.updateFlag}" render=":test"/>
</h:commandButton>
</h:form>
<h:panelGroup rendered="#{backingTest.flag}">
<my:customtag bean="#{backingTest}" method="printMessage"/>
</h:panelGroup>
</h:panelGroup>
这是关联的支持 bean:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
@ManagedBean
@RequestScoped
public class BackingTest {
private boolean flag = false;
public void printMessage() {
System.out.println("hello");
}
public void updateFlag() {
flag = true;
}
public boolean getFlag() {
return flag;
}
}
当我单击第一个命令按钮时,然后updateFlag()
方法已正确调用,并且第二个命令按钮已正确显示。但是当我单击第二个命令按钮时,它永远不会点击printMessage()
方法。在网络浏览器的 JS 控制台和 HTTP 流量监视器中我可以看到click
事件已成功触发,并且 XHR POST 请求已成功发送。
如果我删除rendered
属性,那么一切都会按预期进行。
这是如何引起的以及如何解决?我正在使用 Mojarra 2.1.25。
您的具体问题是由两个事实引起的:
- 当 JSF 需要解码表单提交操作或提交的输入值时,它还会检查组件是否已呈现(以防止黑客攻击/篡改请求)。
- 请求范围的 bean 会在每个 HTTP 请求上重新创建(一个 ajax 请求也算作一个请求!)。
在您的具体情况下,rendered
条件已评估false
而 JSF 需要解码表单提交操作,因此从未处理未呈现的输入/命令组件。
将 bean 放入视图范围内应该可以修复它。下面的示例假设 JSF 2.x。
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ManagedBean
@ViewScoped
下面的示例假设 JSF 2.2+ 带有 CDI:
import javax.inject.Named;
import javax.faces.view.ViewScoped;
@Named
@ViewScoped
或者,如果技术要求是让bean保持在请求范围内,则将后面的条件带过去rendered
属性在一个<o:inputHidden>。调整您的代码片段以将其包含在<h:form>
.
<o:inputHidden value="#{backingTest.flag}" />
也可以看看:
-
commandButton/commandLink/ajax 操作/侦听器方法未调用或输入值未设置/更新- 第 6 点
- 如何选择合适的bean范围?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)