Избегать дублирования идентификаторов при повторном использовании композиций масок в одном и том же контейнере для именования

У меня есть <ui:composition>, который содержит несколько элементов с явными идентификаторами и некоторыми событиями ajax, которые ссылаются на эти идентификаторы для частичной обработки/обновления. Я инкапсулировал этот фрагмент xhtml внутри композиции просто так, чтобы использовать его в нескольких разных местах без дублирования кода. Однако, когда я использую состав (с <ui:include>) более одного раза внутри страницы, я получаю дубликаты исключений. Кажется, JSF не обматывает каждую композицию внутри своего собственного контейнера именования (например, <ui:component>).

Есть ли простой способ обернуть мою композицию внутри собственного контейнера именования? Или мне нужно использовать составной компонент каждый раз, когда я хочу повторно использовать xhtml-фрагменты внутри общего контейнера именования?

Ответ 1

В зависимости от назначения шаблона <ui:include> у вас есть несколько вариантов:

  • Используйте <f:subview>. Он создает другой контекст NamingContainer (например, как <h:form>, <h:dataTable> и все друзья):

    <f:subview id="top">
        <ui:include src="/WEB-INF/includes/some.xhtml" />
    </f:subview>
    ...
    <f:subview id="bottom">
        <ui:include src="/WEB-INF/includes/some.xhtml" />
    </f:subview>
    

    Компоненты, определенные в some.xhtml, получат соответственно префикс top: и bottom: в их идентификаторе.


  • Поверните его в файл тега , для которого требуется атрибут id.

    <my:some id="top" />
    ...
    <my:some id="bottom" />
    

    И используйте этот идентификатор для префикса идентификатора компонентов в композиции.

    <ui:composition 
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:ui="http://java.sun.com/jsf/facelets"
    >
        ...
        <h:someComponent id="#{id}_some" />
        <h:otherComponent id="#{id}_other" />
        ...
    <ui:composition>
    

  • превратите его в составной компонент . Компонентные компоненты по существу уже являются NamingContainer, поэтому их атрибут id не является обязательным. В основном замените

    <ui:composition 
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:ui="http://java.sun.com/jsf/facelets"
    >
        ...
    <ui:composition>
    

    по

    <ui:component 
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:cc="http://java.sun.com/jsf/composite"
    >
        <cc:interface>
            <!-- This is optional. -->
        </cc:interface>
        <cc:implementation>
            ...
            <h:someComponent id="some" />
            <h:otherComponent id="other" />
            ...
        </cc:implementation>
    <ui:component>
    

    Таким образом вы можете использовать его следующим образом:

    <my:some id="top" />
    ...
    <my:some id="bottom" />
    

    Компоненты, определенные в <cc:implementation>, получат соответственно префикс top: и bottom: в их идентификаторе (обратите внимание, что атрибут составного компонента id не является обязательным, JSF будет в противном случае автогенерировать один).


См. также:

Ответ 2

Когда вы включаете более одного раза те же ui:composition, дублируются идентификаторы. Решение состоит в том, чтобы указать конкретный ui:param в пределах ui:include.

Предполагая, что вы включаете mycomposition.xhtml, вы можете сделать что-то подобное:

<ui:include src="mycomposition.xhtml">
    <ui:param name="idPrefix" value="first"/>
</ui:include>

...

<ui:include src="mycomposition.xhtml">
    <ui:param name="idPrefix" value="second"/>
</ui:include>

Затем в mycomposition.xhtml вы должны объявить идентификаторы следующим образом (например, h: outputText):

<h:outputText id="#{idPrefix}_text" value="My Awesome Text here"/>

Теперь вы можете ссылаться на id на остальной странице yout как #{idPrefix}_text.