Ответ 1
Ошибка дублирования идентификатора компонента происходит потому, что оба из них физически заканчиваются в дереве компонентов JSF. <h:panelGroup rendered="false">
не мешает им заканчиваться в дереве компонентов JSF, а не мешает им генерировать свой вывод HTML.
Вместо условного вывода их вывода HTML вам необходимо условно построить их в дереве компонентов JSF. JSTL очень полезен в этом, так как он запускается во время времени сборки:
<c:if test="#{bean.insertMode eq 'SINGLE'}">
<ui:include src="_single.xhtml" />
</c:if>
<c:if test="#{bean.insertMode eq 'DOUBLE'}">
<ui:include src="_double.xhtml" />
</c:if>
Если вы используете Mojarra, вам нужно только убедиться, что вы используете хотя бы версию 2.1.18 или новее, иначе просмотр области видимости beans будет вести себя как область с запросом beans.
Альтернативой является использование условного оператора EL в атрибуте src
(сам <ui:include>
работает как обработчик тегов также во время сборки времени):
<ui:include src="_#{bean.insertMode eq 'SINGLE' ? 'single' : 'double'}.xhtml" />
Или даже используйте insertMode
непосредственно как имя файла:
<ui:include src="_#{fn:toLowerCase(bean.insertMode)}.xhtml" />
В любом случае вам нужно обязательно убедиться, что #{bean.insertMode}
доступен во время сборки времени просмотра, а также то, что точно такое же значение доступно во время фазы просмотра восстановления postbacks, как это было во время первоначальной рендеринга, в противном случае представление возможно, будут восстановлены с неправильным включением, и JSF больше не сможет декодировать правильные входы и команду. Кроме того, если вы хотите изменить включение во время обратной передачи, вам действительно нужно перестроить представление (вернуть не null
/void
) или отправить перенаправление.