如何在单个数据表中显示不同对象类型的不同值?
我有一个对象(票证),其中包含其他对象(消息)的列表。 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
我的主要问题是
一些代码:
<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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
比较对象类的名称,而不是 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:chooseAnd 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.