当使用带有条件呈现的p:消息时,Ajax停止工作



环境:JBoss EAP 6.3, Mojarra 2.1.28, JSF 2.0和java 1.7.0_79.

在我的xhtml模板中,我有两个p:消息,如下所示,用于显示全局消息:

<p:messages
    id="globalMessages"
    globalOnly="true"
    autoUpdate="true"
    severity="fatal, error, warn"
    rendered="#{menuMB.renderFatalErrorWarningMessage}" />
<p:messages
    id="globalMessagesInfo"
    globalOnly="true"
    autoUpdate="true"
    severity="info"
    rendered="#{menuMB.renderInfoMessage}" />

菜单中有

@Inject
private FacesContext facesContext;
public boolean isRenderInfoMessage() {
    return facesContext.getMaximumSeverity() == null || facesContext.getMaximumSeverity().equals(FacesMessage.SEVERITY_INFO);
}
public boolean isRenderFatalErrorWarningMessage() {
    return !isRenderInfoMessage();
}

在我使用模板的页面上,我有几个字段,它们各自的p:消息用于错误处理,例如

<h:inputText id="firstName" />
<p:message for="firstName" />

如果提交表单并且在字段firstName上验证失败,则按预期显示本地消息。然而,从这一刻起,ajax调用不再工作。

如果我改变MenuMB方法不使用FacesContext

public boolean isRenderInfoMessage() {
    // return facesContext.getMaximumSeverity() == null || facesContext.getMaximumSeverity().equals(FacesMessage.SEVERITY_INFO);
    return true;
}
public boolean isRenderFatalErrorWarningMessage() {
    // return !isRenderInfoMessage();
    return false;
}

,所有ajax调用都按预期工作。无论我从p:messages中删除渲染选项还是设置渲染=true/false(没有方法调用),都是一样的。

有什么办法解决这个问题吗?

您可能会发现某个地方正在发生异常,该异常正在停止所有未来的调用,很可能是潜在的java脚本问题。

同样根据记忆,你不需要在渲染标签中包装p:消息——它只会在你定义的指定严重性的内容中自动渲染。

目标呈现的一个问题是值必须已经在页面上才能被定位,所以定位一个可能不会被呈现的属性将会失败。最好将sed属性包装在另一个可以定位的标签中,然后它将加载内部内容渲染。

我发现解决我的问题的唯一方法是通过覆盖类MessagesRenderer从primefaces:

package xx.xx.xx.PFMessagesRenderer;
import org.primefaces.component.messages.MessagesRenderer;
public class PFMessagesRenderer extends MessagesRenderer {
    @Override
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
        Messages uiMessages = (Messages) component;
        ResponseWriter writer = context.getResponseWriter();
        String clientId = uiMessages.getClientId(context);
        Map<String, List<FacesMessage>> messagesMap = new HashMap<String, List<FacesMessage>>();
        ////////////////////////////////////////
        // BEGIN CHANGES
        ////////////////////////////////////////
        boolean showInfoMessage = true;
        if (uiMessages.isGlobalOnly()) {
            Iterator<FacesMessage> messages = context.getMessages(null);
            boolean hasInfoMessage = false;
            boolean hasWarnErrorFatalMessage = false;
            while (messages.hasNext()) {
                if (messages.next().getSeverity().equals(FacesMessage.SEVERITY_INFO)) {
                    hasInfoMessage = true;
                } else {
                    hasWarnErrorFatalMessage = true;
                }
            }
            if (hasInfoMessage && hasWarnErrorFatalMessage) {
                showInfoMessage = false;
            }
        }
        ////////////////////////////////////////
        // BEGIN CHANGES
        ////////////////////////////////////////
        String _for = uiMessages.getFor();
        Iterator<FacesMessage> messages;
        if (_for != null) {
            messages = context.getMessages(_for);
        } else {
            messages = uiMessages.isGlobalOnly() ? context.getMessages(null) : context.getMessages();
        }
        while (messages.hasNext()) {
            FacesMessage message = messages.next();
            FacesMessage.Severity severity = message.getSeverity();
            if (severity.equals(FacesMessage.SEVERITY_INFO)) {
                ////////////////////////////////////////
                // BEGIN CHANGES
                ////////////////////////////////////////
                if (showInfoMessage) {
                    addMessage(uiMessages, message, messagesMap, "info");
                }
                ////////////////////////////////////////
                // END CHANGES
                ////////////////////////////////////////
            } else if (severity.equals(FacesMessage.SEVERITY_WARN)) {
                addMessage(uiMessages, message, messagesMap, "warn");
            } else if (severity.equals(FacesMessage.SEVERITY_ERROR)) {
                addMessage(uiMessages, message, messagesMap, "error");
            } else if (severity.equals(FacesMessage.SEVERITY_FATAL)) {
                addMessage(uiMessages, message, messagesMap, "fatal");
            }
        }
        writer.startElement("div", uiMessages);
        writer.writeAttribute("id", clientId, "id");
        writer.writeAttribute("class", "ui-messages ui-widget", null);
        for (String severity : messagesMap.keySet()) {
            List<FacesMessage> severityMessages = messagesMap.get(severity);
            if (severityMessages.size() > 0) {
                encodeSeverityMessages(context, uiMessages, severity, severityMessages);
            }
        }
        writer.endElement("div");
    }
}
在faces-config.xml中我们需要添加
<render-kit>
    <renderer>
        <component-family>org.primefaces.component</component-family>
        <renderer-type>org.primefaces.component.MessagesRenderer</renderer-type>
        <renderer-class>xx.xx.xx.PFMessagesRenderer</renderer-class>
    </renderer>
</render-kit>

这样我的模板页面就可以有一个单独的p:messages,如下所示:

<p:messages
    id="globalMessages"
    globalOnly="true"
    autoUpdate="true"
    severity="error, fatal, warn, info" />

相关内容

  • 没有找到相关文章

最新更新