在有条件渲染的组件中提交表单不会被处理

我有一个自定义标记文件的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。

你的具体问题是由两个事实造成的:

  1. 当JSF需要解码表单提交动作时,它还会检查组件是否被呈现(作为防止黑客/被篡改的请求)。
  2. 请求范围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范围?
Interesting Posts