h:commandButton里面的动作ui:fragment没有被触发

时间:2014-10-29 15:33:16

标签: jsf jsf-2 jsf-2.2

无论如何都会发布表单,但是如果我不将表单放在ui:fragment中,则只会触发按钮操作参数引用的bean方法。我在Tomcat 6.0.41上使用Mojarra 2.2.5。

(如果我使用primefaces' p:commandButton

也会发生这种情况)

view.xhtml?edit=true

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">
    <f:metadata>
        <f:viewParam name="edit" id="edit" />
        <ui:param name="editMode" value="#{not empty edit and edit eq 'true' and saveBean.contentEditable}" />
    </f:metadata>
    <h:head>
        <title>Page title</title>
    </h:head>
    <h:body>
        <ui:fragment rendered="#{editMode}">
        </ui:fragment>
            <h:form id="saveForm">
                <h:commandButton 
                    id="btn2" 
                    type="submit" 
                        value="Triggers POST but no action" 
                    action="#{saveBean.saveAllAction}"
                />
            </h:form>
    </h:body>
</html>

支持bean:

import java.io.Serializable;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ManagedBean(name = "saveBean")
@ViewScoped
public class TestBean implements Serializable{
    private static final long serialVersionUID = 1L;
    private static final Logger log = LoggerFactory.getLogger(TestBean.class);
    public String saveAllAction() {
        log.info("Received save all command.");
        return "success";
    }
    public TestBean() {}
    public String getContentEditable() {
        return contentEditable;
    }
    public void setContentEditable(String contentEditable) {
        this.contentEditable = contentEditable;
    }
    private String contentEditable = "true";
}

2 个答案:

答案 0 :(得分:1)

我独立发现的解决方案非常接近@Ali C提出的解决方案:底线是rendered="..."条件在表单发布请求到达时重新评估。通过将条件设置为bean参数(saveBean.editMode):

,可以在这种情况下访问条件
<f:metadata>
    <f:viewParam name="edit" id="edit" value="#{saveBean.edit}"/>
</f:metadata>
...

            <ui:fragment rendered="#{saveBean.editMode}">
            ...

并将属性editeditMode添加到bean。

答案 1 :(得分:1)

阅读this answer到相关问题,我怀疑#5是你的问题,在应用请求阶段(可能是ui:param的时间情况)之后,JSF上的呈现属性被切换,从而导致安全性失败之后重新检查。您可以通过对呈现的属性进行hardcoding true来快速验证问题不是ui:fragment或h:commandButton。

要解决这个问题,让viewParam在支持bean中设置一个属性,然后ui:fragment可以检查该属性而不是检查ui:param。

 <f:metadata>
    <f:viewParam name="edit" id="edit" value="#{saveBean.editMode}"/>
</f:metadata>
  ...
   <ui:fragment rendered="#{saveBean.editMode}">