在有条件渲染的组件中提交表单不会被处理
我有一个自定义标记文件的forms:
<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; } }
当我点击第一个命令button,然后正确调用updateFlag()
方法,并正确显示第二个命令button。 但是,当我然后单击第二个命令button,它从来没有击中printMessage()
方法。 在Web浏览器的JS控制台和HTTPstream量监视器中,我可以看到click
事件被成功激发,并且XHR POST请求被成功发送。
如果我删除rendered
属性,那么一切按预期工作。
这是如何造成的,我该如何解决? 我正在使用Mojarra 2.1.25。
你的具体问题是由两个事实造成的:
- 当JSF需要解码表单提交动作时,它还会检查组件是否被呈现(作为防止黑客/被篡改的请求)。
- 请求范围bean在每个HTTP请求上重新创build(ajax请求也被视为一个请求!)。
在您的具体情况下, rendered
条件评估为false
而JSF需要解码表单提交操作,因此从不处理非呈现的input/命令组件。
把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
也可以看看:
- commandButton / commandLink / ajax操作/侦听器方法未被调用或input值未更新 – 点5
- 如何select合适的bean范围?