JSF2 commandButton操作未在更新的片段中调用

时间:2015-02-27 09:05:44

标签: jsf jsf-2 primefaces jsf-2.2

我在表单中有命令按钮。在页面加载时呈现的那些是调用操作, 但是<p:fragment>标记中的那两个在回发时呈现并且无法正常工作。

<h:form>
    <p:commandButton action="#{bean.actionA()}"/>
    <p:commandButton actionListener="#{bean.actionB()}"/>

    <p:fragment rendered="#{not empty bean.field}">
        <p:commandButton action="#{bean.actionA()}"/>
        <p:commandButton actionListener="#{bean.actionB()}"/>
    </p:fragment>

    <ui:include ..>
        ...
        <p:commandLink update="@form">
            <i class="fa fa-folder"></i>
            <f:setPropertyActionListener value="#{data.document}" target="#{bean.field}" />
        </p:commandLink>
    </ui:include>
</h:form>

我是JSF的菜鸟。我知道这个问题与JSF生命周期有关,但我找不到可行的解决方案。

我的bean是视图范围,我使用的是primefaces 5.1。

这是假设工作还是我在显示/隐藏按钮的错误方法?

感谢。

编辑:

经过一些测试后,即使调用了动作,也会在null==bean.field的bean上调用它。 这对我来说没有意义,因为我在完成更新后会显示值#{bean.field.name}并显示隐藏的按钮。

我错过了什么?

update=@form更改为update=@all时效果相同。

感谢任何帮助。

我的会话范围的bean喜欢这个。在这种情况下SessionScoped按钮正在工作。为什么查看范围不够?

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ActionEvent;
import javax.faces.view.ViewScoped;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

//TODO: change to @ViewScoped
@ManagedBean(name="bean")
@SessionScoped
public class Bean extends BeanBase {

private static final long serialVersionUID = 1L;
    private static final Logger LOGGER = LogManager.getLogger(Bean.class.getName());

    @PostConstruct
    protected void init() {
        super.init();
    }

    public void actionA() {
        LOGGER.debug("Action A triggerd!");
    }
    public void actionB( ActionEvent event) {
        LOGGER.debug("Action B event triggerd!");
        super.edit(event);
    }
}

View in browser. At bottom is icon that triggers in the middle rendered arrea. Buttons in that arrea are not active.

1 个答案:

答案 0 :(得分:1)

首先,p:fragment标记应该用于在AJAX调用期间部分提交和处理表单的片段,而无需直接在相应的组件上显式定义此行为。如果你只想要一组组件的caontional渲染,最好只使用例如p:outputPanel

但是造成这里问题的原因是,渲染的属性不仅在表单必须呈现时进行评估,而且还在处理表单时进行评估。如果由于某种原因,渲染的attribut中的表达式现在被评估为false,那么将停止处理表单并且不会调用该操作。出于安全原因。

在您的情况下,field在表单被预处理时被评估为null,因此commandButton的父级的呈现属性被计算为false,这就是为什么action方法是没有被援引。

原因是,ManagedBean的Scope由于某种原因变小,和/或在渲染响应阶段后被销毁,因此,当您单击命令按钮时,您正在使用完整的托管bean的新实例,其中field的值从未设置过。

最有可能的是,您的ManagedBean处于请求范围内,而不是视图范围,正如您所期望的那样。检查您是否使用了正确的注释,将Bean置于正确的范围内,并且您没有混淆JSF和CDI注释。