ui:repeat 中条件渲染子类的 PropertyNotFoundException

Posted

技术标签:

【中文标题】ui:repeat 中条件渲染子类的 PropertyNotFoundException【英文标题】:PropertyNotFoundException on conditionally rendered subclasses in ui:repeat 【发布时间】:2014-10-24 23:49:18 【问题描述】:

我有一个超类Person

public class Person 
    public abstract Type getType();

我有它的 2 个子类:

public class JuridicalPerson extends Person 
    public Type getType() 
        return Type.JP;
    
    public List<JuridicalBelong> getJuridicalBelongs() 
        return juridicalBelongs;
    

public class NaturalPerson extends Person 
    public Type getType() 
        return Type.NP;
    
    public List<NaturalBelong> getNaturalBelongs() 
        return naturalBelongs;
    

JuridicalBelongNaturalBelong 属性不同,不能子类化。

我将它们放在 List&lt;Person&gt; 中,我想在 JSF/Facelets 中展示如下:

<ui:repeat value="#bean.persons" var="person">
    <h:panelGroup rendered="#person.type eq 'JP'">
        <ui:repeat value="#person.juridicalBelongs" var="juridicalBelong">
            ...
        </ui:repeat>
    </h:panelGroup>
    <h:panelGroup rendered="#person.type eq 'NP'">
        <ui:repeat value="#person.naturalBelongs" var="naturalBelong">
            ...
        </ui:repeat>
    </h:panelGroup>
</ui:repeat>

但是,这会导致以下异常:

javax.el.PropertyNotFoundException:“com.example.NaturalPerson”类没有“juridicalBelongs”属性。

这怎么可能?根据我的rendered 条件

<h:panelGroup rendered="#person.type eq 'JP'">

它应该忽略NaturalPerson,对吧?

【问题讨论】:

【参考方案1】:

这是由 Mojarra 的 &lt;ui:repeat&gt; 的状态管理中的错误引起的,当您在 &lt;ui:repeat&gt; 中使用 EditableValueHolder 组件(输入字段)时,该错误也会暴露出来。这是根据issue 3219 修复的。该修复程序在Mojarra 2.2.7 中可用,对于根据issue 3224 向后移植到Mojarra 2.1.29 的JSF 2.0/2.1。所以至少升级到那个版本(或者只是根据Mojarra homepage 提供的最新版本)应该可以做到。

否则,最好的办法是将&lt;ui:repeat&gt; 替换为&lt;c:forEach&gt;

【讨论】:

你总是有正确的答案!感谢您分享您的知识@BalusC !!! :)【参考方案2】:

在我的情况下,我没有选择升级 Mojarra 的版本并避免 c:forEach(与 ui 可选渲染组件一起使用时会导致许多副作用)我将 ui:repeat 替换为 ap:dataList 并且它有效. 你必须做一些 CSS 样式来隐藏项目符号,但我认为它物有所值。 我希望它可以帮助某人;)

【讨论】:

以上是关于ui:repeat 中条件渲染子类的 PropertyNotFoundException的主要内容,如果未能解决你的问题,请参考以下文章

React中条件渲染

React中条件渲染和循环

vue.js中条件渲染中的数组子项

关于vue.js中条件渲染的联系

有条件地渲染 tr,使用 ui:repeat 构建表

如何使用 <f:ajax render> 重新渲染 <ui:repeat>