使用复合组件

时间:2017-03-17 16:49:58

标签: jsf jstl composite-component

在使用<c:if>有条件地使用复合组件时,我收到重复的ID异常 我知道这个编译/渲染时间问题,但我真的不知道为什么下面的例子不起作用。 请看一下以下三个简单的片段

名为 TestBean 的会话范围bean,它包含一个布尔值,以及两个将此值更改为true或false的ajax侦听器:

@Named
@SessionScoped
public class TestBean implements Serializable {

    private boolean isVisible = false;

    public void onSetItemVisible(AjaxBehaviorEvent e) {
        this.isVisible = true;
    }

    public void onSetItemInvisible(AjaxBehaviorEvent e) {
        this.isVisible = false;
    }

    public boolean isItemVisible()  {
        return this.isVisible;
    }
}

一个名为 testCmp 的非常简单的复合组件:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:cc="http://java.sun.com/jsf/composite">

    <cc:interface/>
    <cc:implementation>
        <h:outputText id="text" value="text"/>
     </cc:implementation>
</html>

一个允许在隐藏/显示此复合组件

之间切换的视图页面
<h:body>
    <h:form id="testForm">

        <c:if test="#{testBean.itemVisible}">
            <test:testCmp id="test1"/>
        </c:if>
        <p/>

        <test:testCmp id="test2"/>
        <p/>

        <!-- show/hide dynamic item -->
        <h:commandLink value="Show Item">
            <f:ajax execute="@this" listener="#{testBean.onSetItemVisible}" render="@form"/> 
        </h:commandLink>
        <br/>
        <h:commandLink value="Hide Item">
            <f:ajax execute="@this" listener="#{testBean.onSetItemInvisible}" render="@form"/>
        </h:commandLink>
    </h:form>
</h:body>

事情是:当我在show / hide之间切换时,我得到一个重复的ID异常。 异常说:“组件ID testForm:test2:文本已在视图中找到”

它抱怨'test2'......没有条件添加的组件。 当我不使用复合组件并将其替换为<h:outputText>之类的标准组件时,任何方法都可以正常工作。 要重现错误,重要的是,复合组件在同一页面上使用两次,一次使用,而其他时间没有条件。

经过进一步搜索,我发现另一个我认为和我一样有问题的家伙。但他的例子看起来有点复杂,难以重现。 Duplicate component ID in JSF using composite component twice in view

任何人都有线索在这里发生什么? 我的设置是JBoss EAP7和Mojarra JSF 2.2.14(但我也测试了JSF 2.3.0-m11) 有人可以确认这个问题吗? 如果是这样,我会为mojarray家伙制造一个错误。

2 个答案:

答案 0 :(得分:2)

这绝对是Mojarra中的一个错误,与在某些情况下处理动态组件树修改有关。

我创建了一个复制品,提交了一个问题,并将我的发现写到了mojarra dev邮件列表中。请在https://github.com/tuner/mojarra-dynamic-include-reproducer

了解详情

答案 1 :(得分:1)

data = objects.map(item => { return item.speed; }) labels = objects.map(item => { return formatAMPM(item.fixTime); }) 内使用<c:if>时遇到了同样的问题。 绕过我发现的这个错误的唯一方法是使用<cc:implementation>而不是<h:panelGroup rendered="#{condition}">