Получить идентификатор родительского контейнера имен в шаблоне для атрибута render/update

У меня есть шаблон и в его определении я использую несколько форм и кнопок.

Проблема заключается в том, что определение (определение) файла xhtml не знает иерархии компонентов.

И, например, я хочу обновить элемент "table2" в другой форме в том же файле определения.

Вставка шаблона:

<p:tabView id="nav"> <!-- nav -->
    <ui:insert name="content_nav">content navigation</ui:insert>
</p:tabView>

определяет первый уровень моей иерархии "nav"

Шаблон define:

<ui:define name="content_nav">
    <h:form id="form1"> <!-- nav:form1 -->
        <h:dataTable id="table1"/> <!-- nav:form1:table1 -->
        <p:inputText value="#{bean.value}"/>
        <p:commandButton action="..." update="nav:form2:table2"/>
    </h:form>
    <h:form id="form2">
        <h:dataTable id="table2"/> <!-- nav:form2:table2 -->
        <!-- other elements -->
    </h:form>
</ui:define>

В моей определяющей части я не хочу знать "nav"!

Как я могу это сделать? или как я могу переместить один компонент именования вверх?, или сохранить самый высокий родительский полный идентификатор в переменной?

иногда я видел что-то вроде:

update=":table2"

Но я не мог найти информацию об этом?, документация JavaEE 6 просто упоминает @keywords.

Ответ 1

Ужасно, но это должно сработать для вас:

<p:commandButton action="..." update=":#{component.namingContainer.parent.namingContainer.clientId}:form2:table2" />

Поскольку вы уже используете PrimeFaces, альтернативой является использование #{p:component(componentId)}, эта вспомогательная функция сканирует весь корень представления для компонента с данным идентификатором, а затем возвращает его идентификатор клиента:

<p:commandButton action="..." update=":#{p:component('table2')}" />

Ответ 2

Уродный ответ хорошо работает

update=":#{component.namingContainer.parent.namingContainer.clientId}:form2:table2

в основном более полезное обновление из открытого диалога в родительский datatable

Ответ 3

Попробуйте следующее:

<h:commandButton value="Click me">
    <f:ajax event="click" render="table" />
</h:commandButton>

Ответ 4

В дополнение к вышеприведенным решениям у меня возникла проблема: мне пришлось динамически генерировать обновляемые компоненты (многие) на основе логики на стороне сервера (возможно, сложнее обнаружить вложенность).

Таким образом, решение на стороне сервера является эквивалентным update=":#{p:component('table2')}" 1 которое использует org.primefaces.util.ComponentUtils.findComponentClientId( String designId ):

// UiPnlSubId is an enum containing all the ids used within the webapp xhtml.
// It could easily be substituted by a string list or similar.
public static String getCompListSpaced( List< UiPnlSubId > compIds ) {

    if ( compIds == null || compIds.isEmpty() )
        return "" ;
    StringBuffer sb = new StringBuffer( ":" ) ;
    for ( UiPnlSubId cid : compIds )
        sb.append( ComponentUtils.findComponentClientId( cid.name() ) ).append( " " ) ;
    return sb.deleteCharAt( sb.length() - 1 ).toString() ;  // delete suffixed space
}

вызываемый каким-либо другим способом, использующим его, например. например ... update="#{foo.getCompListComputed( 'triggeringCompId' )}".

1: сначала я попробовал, не слишком много думая о возврате public static String getCompListSpaced0() { return ":#{p:component('table2')}" ; } в выражении ... update="#{foo.getCompListSpaced0()}, которое, конечно (после того, как мы подумали о том, как работает структура):) не разрешено (возвращается как есть) и может вызвать проблемы, с которыми сталкиваются некоторые пользователи. Также моя среда Eclipse/JBoss Tools предложила написать :#{p.component('table2')} ( "." Вместо ":" ), что не помогло - конечно.

Ответ 5

Вы можете использовать атрибут binding для объявления переменной EL, связанной с компонентом JSF. Затем вы можете получить доступ к абсолютному идентификатору клиента этого компонента с помощью javax.faces.component.UIComponent.getClientId(). См. Пример ниже:

<t:selectOneRadio 
   id="yourId"
   layout="spread"
   value="#{yourBean.value}"
   binding="#{yourIdComponent}">
       <f:selectItems value="#{someBean.values}" />
</t:selectOneRadio>
<h:outputText>
   <t:radio for=":#{yourIdComponent.clientId}" index="0" />
</h:outputText>