Избегайте дублирования идентификаторов при повторном использовании композиций Facelets в том же контейнере именования
У меня есть <ui:composition>
он содержит несколько элементов с явными идентификаторами и некоторые события ajax, которые ссылаются на эти идентификаторы для частичной обработки / обновления. Я инкапсулировал этот фрагмент xhtml внутри композиции просто для того, чтобы я мог использовать его в нескольких разных местах без дублирования кода. Тем не менее, когда я использую композицию (с <ui:include>
) более одного раза на странице, я получаю дубликаты идентификаторов исключений. Кажется, JSF не оборачивает каждую композицию в свой собственный контейнер имен (например, <ui:component>
делает).
Есть ли простой способ обернуть мою композицию в собственный контейнер имен? Или мне нужно использовать составной компонент каждый раз, когда я хочу повторно использовать фрагменты xhtml внутри общего контейнера имен?
2 ответа
В зависимости от цели <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.Превратите его в файл тегов, который требует
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 автоматически сгенерирует его).
Смотрите также:
Когда вы включаете более одного раза 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
,