Используйте выражение EL для передачи идентификатора компонента в составной компонент в JSF

Проблема: Я передаю выражение 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>

Предполагается, что я передам абсолютный идентификатор компонента в качестве атрибута updateId как это:

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

Проблема в том, что выражение EL для updateId оценивается по объему <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 считает, что я пытаюсь обновить компонент с помощью идентификатора updatingPanel который находится внутри композитного компонента.

Почему выражение EL не оценивается из внешней области видимости: <custom:MenuTable/>?

Есть несколько связанных ответов, но я не понимаю их, таких как этот.

Использование Мохарры 2.1.15

1 ответ

Решение

Выражения EL не оцениваются в момент создания компонента, но в момент обращения к атрибуту. Другими словами, они являются временем выполнения, а не временем сборки. #{component} относится к текущему компоненту пользовательского интерфейса в момент вычисления выражения EL, что в вашем конкретном случае <p:commandLink>, Это объясняет другой результат.

Вам нужно подходить к этому по-другому, не используя #{component}, Одним из способов является

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

Если это все еще не работает, то убедитесь, что вы не используете <h:form prependId="false">,

Смотрите также:

Другие вопросы по тегам