22

在支持 bean 的 @PostConstruct 方法中,我调用了一个 EJB,它可能会返回一些我想通过 p:messages 显示在页面上的消息。然而,即使我添加了 FacesMessages,例如 FacesContext.getCurrentInstance().addMessage(...),p:messages 也不会被 FacesMessages 更新。

如果我改为对来自页面的操作调用 EJB(例如,用户单击页面上的按钮,该按钮调用调用 EJB 的方法,然后添加 FacesMessage(s)),则消息显示使用 p :messages 符合预期。

如何在 @PostConstruct 期间添加 Faces 消息并在最初呈现页面时显示它们?

代码:

Page1Controller.java:

@ManagedBean
public class Page1Controller
{
    @PostConstruct
    public void init()
    {
        FacesContext.getCurrentInstance().addMessage(null, 
            new FacesMessage("Test Message from @PostConstruct"));
    }

    public String getValue()
    {
            return "Some Value";
    }

    public void triggerMessage(ActionEvent event)
    {
            FacesContext.getCurrentInstance().addMessage(null, 
                    new FacesMessage("Test Message from Trigger Button"));      
    }

}

page1.xhtml

   <h:form>
        <p:messages showDetail="true" showSummary="true" autoUpdate="true"/>
        <h:outputText value="#{page1Controller.value}"/>
        <br/>
        <p:commandButton value="Trigger Message" 
                         actionListener="#{page1Controller.triggerMessage}"/>  
   </h:form>
4

3 回答 3

21

在添加消息之前呈现消息组件时,可能会发生这种情况。

在您的具体示例中,组件第一次引用 bean <h:outputText>,因此在那个时候第一次构造。但是该<h:outputText>组件出现在组件之后的特定示例中<p:messages>,因此该<p:messages>组件已经呈现,因此显示消息为时已晚。

您需要确保在呈现消息组件之前以某种方式添加消息。一种方法是使用<f:viewAction>. 它在INVOKE_APPLICATION阶段之前的RENDER_RESPONSE阶段运行。因此它在渲染任何组件之前运行。因此,这是一个绝佳的机会。

<f:metadata>
    <f:viewAction action="#{bean.onload}" />
</f:metadata>

public void onload() {
    // Add message here instead of in @PostConstruct.
}

也可以看看:

于 2012-04-17T19:59:28.367 回答
2

您可以收集错误,然后在加载页面结束时使用具有 autorun = true 模式的 primefaces 的 remoteCommand 显示它。在我的例子中,我有一个 viewScope,在 xhtml 中我显示了在 @PostConstruct 中加载的值列表。如果生成异常,我将在页面加载结束时使用 remoteCommand 将其保存到示例中。

private ArrayList<Exception> postConstucError = new ArrayList<>();

@PostConstruct
public void validarAcceso() {
    /**
     * verificar permisos a la vista de coeficientes
     */
    try {
            this.init() //load data;
        } catch (Exception e) {
        System.out.print(e.getMessage());
        this.postConstucError.add(e);
    }
}

 public void showPostConstructError() {
    try {
        for (int i = 0; i < this.postConstucError.size(); i++) {
            JsfUtil.addErrorMessage("Error al cargar datos iniciales: " + postConstucError.get(i).getMessage());
        }
    } catch (Exception e) {
        JsfUtil.addErrorMessage(e, "Error: showPostConstructError() " + e.getMessage());
    }
}

xhtml代码

  <p:messages id="messages" showDetail="true" autoUpdate="true" closable="true"/> 
  <h:form>
        <p:remoteCommand id="rcomerror" name="showError" process="@this"  autoRun="true"
                         actionListener="#{mBPresentNinos.showPostConstructError()}" />  
    </h:form>
于 2017-04-05T14:30:27.880 回答
0

对我来说,使用 preRenderView 事件在表单初始化上显示消息是一个消息地狱。所以我创建了非常简单的“组件”来保存静态消息。对于此示例,仅支持一条错误消息。

静态消息.xhtml:

<ui:fragment xmlns="http://www.w3.org/1999/xhtml"
             xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
             rendered="#{rendered}">
    <div id="staticMessage" class="ui-messages ui-widget" aria-live="polite">
        <div class="ui-messages-error ui-corner-all"><span class="ui-messages-error-icon"/>
            <ul>
                <li>
                    <span class="ui-messages-error-summary">#{value}</span>
                </li>
            </ul>
        </div>
    </div>
</ui:fragment>

包括消息:

 <ui:include src="/template/components/staticMessage.xhtml">
     <ui:param name="rendered"value="#{beanMB.staticMessagesRendered}"/>
     <ui:param name="value" value="Place your message here."/>
 </ui:include>
于 2018-04-24T09:18:25.583 回答