如何在单个数据表中显示不同对象类型的不同值?

发布于 2024-11-15 00:55:55 字数 1205 浏览 3 评论 0原文

我有一个对象(票证),其中包含其他对象(消息)的列表。 Message 是抽象的,并且有几个子类 - 例如 EditMessage、CreationMessage 等。因此,票证对象包含这些消息的混合,并且它们按创建时间排序。

现在我想在 Facelets 页面中显示所有这些消息,并且需要输出特定于该消息类型的字段值:即 EditMessage 中的editedField、CreationMessage 中的 userName,...

最明显的方法似乎是使用 h: dataTable:

<h:dataTable value="#{ticketController.ticket.messages}" var="msg" >
    // determine type of message, cast, and use <c:if> to output needed values
</h:dataTable>

问题是 Facelets 表达式语言没有“instanceof”和强制转换。据我所知,这可以通过使用一些丑陋的托管 bean 往返、确定标准 Java 中的消息类型、返回所需类型的消息等来解决。

有没有更好、更容易理解、更简洁的方法来做到这一点?


Solution

我的主要问题是标签。事实证明,它是一个 JSTL 标签,因此它的渲染生命周期略有不同。我现在使用来代替它。及其“渲染”属性。

一些代码:

<h:dataTable value="#{ticketController.ticket.messages}" var="msg" >
    <h:column>
        <h:panelGroup rendered="#{msg.class.name == 'org.rogach.tsnt.TextMessage'}" >
            <h:outputText value="msg.text" />
        </h:panelGroup>
        <h:outputText value="#{msg.creationTime}" />
    </h:column>
</h:dataTable>

并且不需要强制转换。

I have an object (Ticket), which has a list of other objects (Message). Message is abstract, and has several subclasses - like EditMessage, CreationMessage, and so on. So that Ticket object contains a mix of that messages, and they are ordered by their creation time.

Now I want to display all those messages in a Facelets page, and I need to output values of fields, specific for that message type: i.e., editedField in EditMessage, userName in CreationMessage, ...

The most obvious way seems to use h:dataTable:

<h:dataTable value="#{ticketController.ticket.messages}" var="msg" >
    // determine type of message, cast, and use <c:if> to output needed values
</h:dataTable>

The problem is that Facelets expression language does not have "instanceof" and casts. As far as I can see, this can be solved using some ugly round-tripping to managed bean, determining type of message in standard Java, return message of needed type, ... and so on.

Is there a better, more understandable and concise way of doing this?


Solution

My main problem was with <c:if> tag. It turned out that it is a JSTL tag, so it has slightly different rendering life cycle. Instead of it, I now use <h:panelGroup> and its "rendered" attribute.

Some code:

<h:dataTable value="#{ticketController.ticket.messages}" var="msg" >
    <h:column>
        <h:panelGroup rendered="#{msg.class.name == 'org.rogach.tsnt.TextMessage'}" >
            <h:outputText value="msg.text" />
        </h:panelGroup>
        <h:outputText value="#{msg.creationTime}" />
    </h:column>
</h:dataTable>

And no cast is ever needed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

云柯 2024-11-22 00:55:55

比较对象类的名称,而不是 instanceof
说:
或 c:choose
而且 EL 不需要任何演员表。如果该对象没有您指定的某些属性,它将给出异常,如果有也没关系。

Instead of instanceof, compare the name of the object's class.
Say:
<c:if test="${xxx.class.name == 'CreationMessage'}"> or c:choose
And you won't need any cast with EL. If the object doesn't have some property you specified it will give an exception, if it does have it's OK.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文