<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()
方法中设置为message
的FacesMessage
出现了很短的时间,然后像轻弹一样突然消失(在当前的示例中,我通过在两者之间添加警告框使其暂停)。
罪魁祸首是<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人员提出增强请求。