使用EL表达式将组件ID传递给JSF中的复合组件

时间:2013-01-11 03:50:02

标签: ajax jsf jsf-2 el composite-component

问题:我将EL表达式传递给复合组件,但EL表达式是从复合组件内部而不是之前评估的。意图是EL表达式求值为字符串,并发送给复合组件。

我有一个复合组件MenuTable

<cc:interface>
    <cc:attribute name="model" type="nz.co.tradeintel.web.MenuTable"/>
    <cc.attribute name="updateId" /> 
</cc:interface>

<cc:implementation>
    <h:panelGroup id="menuTable">
    <table>
        <ui:repeat id="repeat1" value="#{cc.attrs.model.rows}" var="row">
            <tr>
            <ui:repeat id="repeat2" value="#{row.contents}" var="entry">
                <td>
                    <p:commandLink action="#{cc.attrs.model.setSelected(entry)}" update="#{cc.attrs.updateId}" value="#{entry.toString()}"/>
                </td>
            </ui:repeat>
            </tr>
        </ui:repeat>
    </table>
    </h:panelGroup>
</cc:implementation>

目的是我传递绝对组件ID作为属性updateId,如下所示:

<p:PanelGroup id="updatingPanel">
    <!-- Lots of components.-->
</p:PanelGroup>
<custom:MenuTable updateId="#{component.clientId}:updatingPanel" model="#{menuBackBean.menuTable}" />  

问题是,updateId的EL表达式是从复合组件中<p:commandLink />的范围计算得出的,我得到以下错误:

javax.faces.FacesException: Cannot find component with identifier ":j_idt37:j_idt39:updatingPanel:j_idt61:repeat1:0:repeat2:0:j_idt65:updatingPanel" referenced from "j_idt37:j_idt39:updatingPanel:j_idt61:repeat1:0:repeat2:0:j_idt65".

注意:JSF认为我正在尝试更新一个组件,其ID为updatingPanel in 复合组件。

为什么不从外部范围评估EL表达式:<custom:MenuTable/>

有一些相关的答案,但我不理解它们,例如this one

使用Mojarra 2.1.15

1 个答案:

答案 0 :(得分:6)

在构建组件时不会评估EL表达式,但是在访问该属性时。换句话说,它们是运行时而不是构建时间#{component}在评估EL表达式时引用current UI component,在您的特定情况下为<p:commandLink>。这解释了不同的结果。

您需要以不同方式处理此问题,而不使用#{component}。其中一种方式是

<p:panelGroup binding="#{updatingPanel}">
    ...
</p:panelGroup>
<custom:MenuTable ... updateId=":#{updatingPanel.clientId}" />

如果仍然无效,请确保不使用<h:form prependId="false">

另见: