p:向导和消息组件,自动更新设置为true



<p:wizard>执行最后一步后,需要在<p:messages>和/或<p:growl>上显示消息,然后再转发回第一步,如下所示(向导执行三个步骤)

<h:form id="form">
    <p:messages id="message" for="message" redisplay="false" showDetail="true" autoUpdate="true"/>
    <p:wizard widgetVar="wizard">
        <p:tab title="Tab 1"></p:tab>
        <p:tab title="Tab 2"></p:tab>
        <p:tab title="Tab 3">
            <p:commandButton process="@this"
                             oncomplete="alert('Message'); PF('wizard').loadStep(PF('wizard').cfg.steps[0], true)"
                             value="Submit"
                             actionListener="#{bean.action}"/>
        </p:tab>
    </p:wizard>
</h:form>

被管理bean:

@Named
@ViewScoped
public class Bean implements Serializable {
    private static final long serialVersionUID = 1L;
    public Bean() {}
    public void action() {
        FacesMessage message = new FacesMessage();
        message.setSeverity(FacesMessage.SEVERITY_INFO);
        message.setSummary("Message Summary");
        message.setDetail("Message from backing bean");
        FacesContext.getCurrentInstance().addMessage("message", message);
    }
}

在bean的action()方法中设置为messageFacesMessage出现了很短的时间,然后像轻弹一样突然消失(在当前的示例中,我通过在两者之间添加警告框使其暂停)。

罪魁祸首是<p:commandButton>oncomplete处理器中的JavaScript代码。

PF('wizard').loadStep(PF('wizard').cfg.steps[0], true)

这将向导从最后一步转回到第一步,导致自动更新的<p:messages>组件消失。

忽略自动更新(即将其设置为false)在实际项目中不是一个选项,也不能将ignoreAutoUpdate设置为true,因为<p:commandButton>本身不负责执行此任务。

如何防止该代码更新<p:messages>组件,使其一致地显示所述消息/s ?


值得注意的是,在实际情况中,<p:messages>被放置在<h:body>最开始的主模板上,目的是显示一些全局消息,对应于从服务层抛出的一些异常,比如javax.persistence.OptimisticLockException。因此,在<p:messages>上应用一些条件将影响全局组件-需要独立于<p:messages>做一些事情。

基于PF源代码,可以通过向ajax回发提供primefaces.ignoreautoupdate=true请求参数来实现ignoreAutoUpdate="true"的效果。然而,我没有看到一个微不足道的方式来传递给loadStep()函数,而不破解JS源代码。

我可以想到一个解决方案,在JS范围内设置一些布尔值,并在pfAjaxSend DOM事件期间检查它,然后将所需的请求参数附加到ajax请求查询字符串,如options.data可用。为了防止全局JS作用域污染,我选择向全局PrimeFaces对象添加一个自定义属性。

<p:commandButton ... oncomplete="PrimeFaces.ignoreAutoUpdate=true; PF('wizard').loadStep(PF('wizard').cfg.steps[0], true)" />
$(document).on("pfAjaxSend", function(event, xhr, options) {
    if (PrimeFaces.ignoreAutoUpdate) {
        options.data += "&primefaces.ignoreautoupdate=true";
        PrimeFaces.ignoreAutoUpdate = false;
    }
});

在ajax回发之前简单地在JS中设置PrimeFaces.ignoreAutoUpdate=true,这种方式也可以在其他地方重用。

这种方法可能值得向PF人员提出增强请求。

最新更新