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

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

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

2 ответа

Решение

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

  1. использование <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.


  2. Превратите его в файл тегов, который требует 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>
    

  3. Превратите это в составной компонент. Композитные компоненты по своей сути уже 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 автоматически сгенерирует его).


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

Когда вы включаете более одного раза 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 вы должны объявить идентификаторы следующим образом (например, a h:outputText):

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

Теперь вы можете ссылаться на идентификатор на остальной части вашей страницы как #{idPrefix}_text,

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