Посмотрите в выводе HTML фактический идентификатор клиента
Вам нужно просмотреть сгенерированный HTML-вывод, чтобы узнать правильный идентификатор клиента. Откройте страницу в браузере, щелкните правой кнопкой мыши и просмотрите исходный код . Найдите HTML-представление интересующего компонента JSF и возьмите его в idкачестве идентификатора клиента. Вы можете использовать его абсолютным или относительным способом в зависимости от текущего контейнера именования. См. Следующую главу.
Примечание: если он содержит индекс итерации, например :0:, :1:и т. Д. (Потому что он находится внутри итерационного компонента), тогда вам необходимо понимать, что обновление определенного раунда итерации не всегда поддерживается. См. Более подробную информацию в нижней части ответа.
Запоминать NamingContainerкомпоненты и всегда давать им фиксированный идентификатор
Если компонент, на который вы хотите ссылаться с помощью процесса / выполнения / обновления / рендеринга ajax, находится внутри одного и того же NamingContainerродителя, просто укажите его собственный идентификатор.
<h:form id="form">
<p:commandLink update="result">
<h:panelGroup id="result" />
</h:form>
Если он не находится внутри одного и того же NamingContainer, вам необходимо указать его, используя абсолютный идентификатор клиента. Абсолютный идентификатор клиента начинается с NamingContainerсимвола-разделителя, который используется по умолчанию :.
<h:form id="form">
<p:commandLink update="result">
</h:form>
<h:panelGroup id="result" />
<h:form id="form">
<p:commandLink update=":result">
</h:form>
<h:panelGroup id="result" />
<h:form id="form">
<p:commandLink update=":result">
</h:form>
<h:form id="otherform">
<h:panelGroup id="result" />
</h:form>
<h:form id="form">
<p:commandLink update=":otherform:result">
</h:form>
<h:form id="otherform">
<h:panelGroup id="result" />
</h:form>
NamingContainerкомпоненты, например <h:form>, <h:dataTable>, <p:tabView>, <cc:implementation>(таким образом, все составные компоненты) и т.д. Вы узнаете их легко, посмотрев на сгенерированном выводе HTML, их ID будет предварять сгенерированный идентификатор клиента всех дочерних компонентов. Обратите внимание: если у них нет фиксированного идентификатора, JSF будет использовать автоматически сгенерированный идентификатор в j_idXXXформате. Вы должны полностью избегать этого, давая им фиксированный идентификатор. В OmniFacesNoAutoGeneratedIdViewHandler может быть полезен в этом процессе разработки.
Если вы знаете, что найти javadoc по рассматриваемому UIComponentвопросу, вы также можете просто проверить там, реализует ли он NamingContainerинтерфейс или нет. Например, HtmlForm( тег UIComponentпозади <h:form>) показывает, что он реализует NamingContainer, но HtmlPanelGroup( тег UIComponentпозади <h:panelGroup>) не показывает его, поэтому он не реализует NamingContainer. Вот javadoc всех стандартных компонентов и javadoc PrimeFaces .
Решение твоей проблемы
Итак, в вашем случае:
<p:tabView id="tabs">
<p:tab id="search">
<h:form id="insTable">
<p:dialog id="dlg">
<h:panelGrid id="display">
Сгенерированный вывод HTML <h:panelGrid id="display">выглядит следующим образом:
<table id="tabs:insTable:display">
Вам нужно взять именно это в idкачестве идентификатора клиента, а затем использовать префикс с помощью :в update:
<p:commandLink update=":tabs:insTable:display">
Обращение за пределами include / tagfile / complex
Если эта командная ссылка находится внутри файла include / tagfile, а цель находится за его пределами, и, таким образом, вы не обязательно знаете идентификатор родительского контейнера именования текущего контейнера именования, вы можете динамически ссылаться на него UIComponent#getNamingContainer()следующим образом:
<p:commandLink update=":#{component.namingContainer.parent.namingContainer.clientId}:display">
Или, если эта командная ссылка находится внутри составного компонента, а цель находится вне его:
<p:commandLink update=":#{cc.parent.namingContainer.clientId}:display">
Или, если и ссылка на команду, и цель находятся внутри одного составного компонента:
<p:commandLink update=":#{cc.clientId}:display">
См. Также Получить идентификатор родительского контейнера именования в шаблоне для атрибута render / update
Как работает под одеялом
Все это определяется как «поисковое выражение» в в UIComponent#findComponent()Javadoc :
Выражение поиска состоит либо из идентификатора (который согласован точно против собственности идентификатора UIComponentили серии таких идентификаторов , связанных по UINamingContainer#getSeparatorCharзначению символов. Алгоритм поиска должен работает следующим образом , хотя альтернативные alogrithms могут быть использованы до тех пор , как конечный результат тот же:
- Определите,
UIComponentчто будет основой для поиска, остановив его, как только будет выполнено одно из следующих условий:
- Если поисковое выражение начинается с символа-разделителя (называемого «абсолютным» поисковым выражением), базой будет корень
UIComponentдерева компонентов. Начальный символ-разделитель будет удален, а оставшаяся часть поискового выражения будет рассматриваться как «относительное» поисковое выражение, как описано ниже.
- В противном случае, если это
UIComponentявляется NamingContainerон будет служить в качестве основы.
- В противном случае найдите родителей этого компонента. Если
NamingContainerвстречается, то это будет база.
- В противном случае (если нет
NamingContainer) корень UIComponentбудет базой.
- Выражение поиска (возможно, измененное на предыдущем шаге) теперь является «относительным» выражением поиска, которое будет использоваться для поиска компонента (если есть), имеющего совпадающий идентификатор, в пределах области действия базового компонента. Матч проводится следующим образом:
- Если поисковое выражение является простым идентификатором, это значение сравнивается со свойством id, а затем рекурсивно проходит через фасеты и дочерние элементы базы
UIComponent(за исключением того, что если потомок NamingContainerнайден, его собственные фасеты и дочерние элементы не ищутся).
- Если поисковое выражение включает более одного идентификатора, разделенного символом-разделителем, первый идентификатор используется для поиска
NamingContainerпо правилам в предыдущем пункте маркера. Затем будет вызван findComponent()метод this NamingContainer, передав остаток поискового выражения.
Обратите внимание, что PrimeFaces также придерживается спецификации JSF, но RichFaces использует «некоторые дополнительные исключения» .
«reRender» использует UIComponent.findComponent()алгоритм (с некоторыми дополнительными исключениями) для поиска компонента в дереве компонентов.
Эти дополнительные исключения нигде подробно не описаны, но известно, что относительные идентификаторы компонентов (то есть те, которые не начинаются с :) ищутся не только в контексте ближайшего родителя NamingContainer, но и во всех других NamingContainerкомпонентах в том же представлении (что является относительно кстати дорогая работа).
Никогда не использовать prependId="false"
Если все это по-прежнему не работает, проверьте, не используете ли вы <h:form prependId="false">. Это завершится ошибкой во время обработки отправки и рендеринга ajax. См. Также этот связанный вопрос: UIForm с prependId = "false" breaks <f: ajax render> .
Ссылка на конкретный итерационный раунд повторяющихся компонентов
Это было в течение длительного времени не представляется возможным ссылаться на конкретный элемент итерация в переборе компонентов , таких как <ui:repeat>и <h:dataTable>как так:
<h:form id="form">
<ui:repeat id="list" value="#{['one','two','three']}" var="item">
<h:outputText id="item" value="#{item}" /><br/>
</ui:repeat>
<h:commandButton value="Update second item">
<f:ajax render=":form:list:1:item" />
</h:commandButton>
</h:form>
Однако, поскольку Mojarra 2.2.5 <f:ajax>начал его поддерживать (он просто прекратил его проверку; таким образом, вы больше никогда не столкнетесь с упомянутым исключением в вопросе; позже для этого планируется другое исправление улучшения).
Это пока не работает только в текущих версиях MyFaces 2.2.7 и PrimeFaces 5.2. Поддержка может появиться в будущих версиях. Между тем, лучше всего обновить сам повторяющийся компонент или родительский компонент, если он не отображает HTML, например <ui:repeat>.
При использовании PrimeFaces учитывайте поисковые выражения или селекторы.
PrimeFaces Search Expressions позволяет ссылаться на компоненты через выражения поиска в дереве компонентов JSF. JSF имеет несколько встроенных функций:
@this: текущий компонент
@form: родитель UIForm
@all: весь документ
@none: ничего
PrimeFaces улучшил это с помощью новых ключевых слов и поддержки составных выражений:
@parent: родительский компонент
@namingcontainer: родитель UINamingContainer
@widgetVar(name): компонент, идентифицированный данным widgetVar
Вы также можете смешивать эти ключевые слова в составных выражениях, таких как @form:@parent, @this:@parent:@parentи т. Д.
PrimeFaces Selectors (PFS), как в, @(.someclass)позволяет ссылаться на компоненты с помощью синтаксиса селектора jQuery CSS. Например, ссылки на компоненты, имеющие все общие классы стилей в выводе HTML. Это особенно полезно, если вам нужно сослаться на "много" компонентов. Это только требует, чтобы целевые компоненты имели весь идентификатор клиента в выводе HTML (фиксированный или автоматически сгенерированный, не имеет значения). См. Также Как работают селекторы PrimeFaces, как в update = "@ (. MyClass)"?