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

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

Использование Mojarra 2.1.15

2
Kevin 11 Янв 2013 в 07:50

1 ответ

Лучший ответ

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

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

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

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

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

7
Community 20 Июн 2020 в 12:12
Я получаю новую ошибку: javax.faces.FacesException: Cannot find component with identifier ":j_idt37:j_idt39:updatingPanel" referenced from "j_idt37:j_idt39:j_idt62:repeat1:0:repeat2:0:j_idt66". Похоже, сгенерированный идентификатор правильный, но все еще не распознается. У меня такое ощущение, что вы решили проблему, а я обнаружил кое-что новое.
 – 
Kevin
11 Янв 2013 в 15:59
Попробуйте дать родителям именованных контейнеров фиксированный идентификатор.
 – 
BalusC
11 Янв 2013 в 16:02
Та же ошибка, но с красивыми именами: javax.faces.FacesException: Cannot find component with identifier ":sellingAdvice:listingSearher:updatingPanel" referenced from "sellingAdvice:listingSearher:menuTable:repeat1:0:repeat2:0:j_idt64". У меня есть все соответствующие компоненты в <ui:fragment/>, которые визуализируются по запросу. Может ли это помешать разрешению идентификаторов?
 – 
Kevin
11 Янв 2013 в 16:09
Нет, условие rendered не учитывается при поиске компонента. Однако подойдут теги времени сборки, такие как <c:if> и <c:choose>. У тебя есть какие-нибудь из них?
 – 
BalusC
11 Янв 2013 в 16:13
Нет, я на собственном горьком опыте научился держаться подальше от <c:if> и <c:choose>. Когда я смотрю на сгенерированный HTML-код, ID, который он, по-видимому, не может найти, правильный, поэтому я не понимаю, почему у него проблема. И ID абсолютный, поэтому искать надо с Root.
 – 
Kevin
11 Янв 2013 в 16:15