JSF 2.0自定义消息

7

我正在使用JSF 2.0。我正在使用

<h:messages>

标签用于呈现错误消息。我可以使用CSS对我的消息进行一些样式设置,但我创建了一个组合组件来呈现消息,该组件可以关闭并使用一些JQuery效果添加效果。

我看过一些关于如何自定义消息的教程,但大多数都依赖于CSS和自定义文本输出,而我想做的是生成特定的标记,例如

<myComp:fancyMessage text="etcetcetc error msg" type="error" />

能否使用自定义的消息标记代替常规的消息标记?

编辑:

我不想为jsf消息添加样式,也不想更改其样式,而是创建自己的消息html标记。在这里:

http://balusc.blogspot.com/2010/07/using-html-in-jsf-messages.html

我已经找到了如何将html添加到您的消息中。我想要的是将所有html封装在我的组合组件中,然后只需以这种方式使用我的组合组件:

<mycomp:messages/>

或者

<mycomp:message for="componentID" />

在这里,message和messages都会创建自己的html标记。


你的问题非常模糊。你说你已经用一些jQuery创建了一个组合组件,然后又问是否可以创建一个自定义(组合)组件。具体问题或者要求是什么? - BalusC
@BalusC 我刚刚在阅读你的博客时偶然发现了这篇文章:http://balusc.blogspot.com/2010/07/using-html-in-jsf-messages.html,但它并不完全符合我的需求。我错过了那篇文章。 - arg20
非常抱歉我的问题表述不够清晰。我的意思是我创建了一个组合组件来显示消息。我需要JSF使用该组合组件来呈现消息。 - arg20
我不希望在消息中包含HTML标记,而是希望放在组件中。 - arg20
啊,是的,我现在明白你的意思了。 - BalusC
3个回答

13
使用 FacesContext#getMessageList()ui:repeat 中。每个项目都是一个具有多个getter的 FacesMessage
<ui:repeat value="#{facesContext.messageList}" var="facesMessage">
    Severity: #{facesMessage.severity}<br />
    Summary: #{facesMessage.summary}<br />
    Detail: #{facesMessage.detail}<br />
    <br />
</ui:repeat>

这样可以在消息周围添加更精细的HTML标记。


同时,借助<h:outputText escape="false">,还可以将其作为HTML打印出来。我可能需要尽快扩展和修订我的博客文章 :)


BalusC,我做到了,它的效果非常好,除了一件事。由于我正在使用自己的消息组件(我将其命名为:<acc:messages>),jsf找不到消息标记,因此它会在页面末尾显示消息。所以最终我渲染了两条消息,一个是我创建的,另一个是jsf的。有没有办法抑制警告或将我的组件注册为消息渲染器? - arg20
1
如果你指的是开发警告消息已经排队但未显示的问题,那么很抱歉我现在不知道。然而,当项目阶段未设置为开发时,这将不会出现。你可能想要使用<h:messages style="display: none;" />来解决这个问题。 - BalusC

3

回答如何将您的组件设置为消息渲染器:

您的组件需要扩展HtmlBasicRenderer。

然后,您可以将您的渲染器添加到faces-config.xml中。

<render-kit>
    <renderer>
        <component-family>javax.faces.Messages</component-family>
        <renderer-type>javax.faces.Messages</renderer-type>
        <renderer-class>com.mypackage.MessagesRenderer</renderer-class>
    </renderer>
</render-kit>

嘿,我的复合组件没有继承自UIComponent,我已经在一个xhtml文件中定义了它。难道没有不创建Java类作为自定义渲染器的方法吗? - arg20
1
目前我还不知道替代方案。几周前刚开始将一个相当大的项目从1.2迁移至2.0。如果我发现关于这个问题的任何信息,我一定会让你知道。 - Chris

1
我知道已经有一段时间了,但是为了让其他人受益,我想分享这个备选方案。对于组合组件,请创建一个带有getter的后备组件,然后在迭代面消息并收集每条消息后调用remove()。这将避免使用h:messages hack时出现“消息已排队”警告。
<composite:interface displayName="Messages Component"
    shortDescription="Messages Component" componentType="com.company.dept.commons.ui.messages.Messages">
    <composite:attribute name="styleClass" default="" type="java.lang.String" shortDescription="CSS style class for the component" />
</composite:interface>

<composite:implementation>
    <div id="messagesComponent" class="#{cc.attrs.styleClass}">
        <ui:repeat value="#{cc.messageList}" var="message">
            #{message.severity} - #{message.detail}<br/>            
        </ui:repeat>
    </div>
</composite:implementation>

后备组件:

@FacesComponent("com.company.dept.commons.ui.messages.Messages")
public class Messages extends UINamingContainer {

    private List<FacesMessage> messages;

    public List<FacesMessage> getMessageList() {
        //preserve messages in case getter is called multiple times
        if (messages == null) {
            messages = new ArrayList<FacesMessage>();
        }

        Iterator<FacesMessage> messageItr = getFacesContext().getMessages();
        while(messageItr.hasNext()) {
            FacesMessage message = messageItr.next();
            messages.add(message);
            messageItr.remove();
        }
        return messages;
    }       
}

请注意,xhtml中的componentType设置为代码中的FacesComponent值。此外,对cc.messageList的引用将触发调用getMessageList()。
希望这可以帮助您。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接