JSF - Динамическое количество вкладок в tabView с динамическим содержимым вкладок
Я новичок в JSF, и я хотел бы получить ваши предложения о том, как реализовать то, что мне нужно, наилучшим образом. Также первый пост в Stackru, поэтому, пожалуйста, извините, если мне что-то не понятно.
У меня есть ap: tabView с динамическим количеством вкладок, сгенерированных с помощью c: foreach следующим образом, с базовым компонентом вида.
<p:tabView id="tabViewId">
<c:forEach items="#{controller.list}" var="aTab">
<p:tab title="#{aTab.label}">
<ui:include src="#{aTab.firstUrl}"/>
</p:tab>
</c:forEach>
</p:tabView>
Это работает, и я доволен этим. Теперь дело в том, что у каждой из моих вкладок есть два возможных представления, и когда происходит определенное событие (в одном из представлений щелкает ap: commandLink), я бы хотел изменить то, что показано на вкладке, на другое представление этой вкладки. есть; другими словами, я бы хотел изменить представление src, загружаемое на вкладку, с помощью ui: include. Я попытался вернуть желаемый путь просмотра в методе, связанном с этим commandLink в контроллере, но, как и ожидалось, он перенаправляет на новую страницу, а не загружает ее внутри вкладки.
Я хотел бы сохранить тот же экземпляр контроллера при переключении содержимого вкладки (мой контроллер имеет область видимости) и избежать привязки.
Я пришел с двумя вариантами.
Сначала нужно попробовать что-то похожее на это (полученное из простых символов tabView различного содержимого вкладок с динамическими вкладками), получить пути просмотра из моего "aTab" вместо их жесткого кодирования, а затем попытаться обновить вкладку или весь tabView на моем commandLink после того, как изменение логического значения, которое переключается между двумя страницами в контроллере:
<ui:include
src="#{curSearch.closeable ? '/sections/search/searchInstanceTab.xhtml' : '/sections/search/firstSearchTab.xhtml'}">
</ui:include>
Второй будет включать обе страницы в каждую вкладку, но отображать только одну, используя логическое значение в контроллере. Это звучит гораздо хуже для меня, чем первый вариант (он предлагается в качестве ответа на вопрос, который я связывал ранее).
Заранее спасибо, пожалуйста, не стесняйтесь предложить любой более легкий / лучший способ.
::: РЕДАКТИРОВАТЬ:::
Наконец, я решил, что каждая вкладка должна быть в отдельном файле xhtml (загружаемом с циклом c: foreach) и в каждой вкладке xhtml / tab все возможные представления (также в отдельных xhtmls) ui: include'd с выражением, жестко закодированным. Довольно плавное решение и прекрасно работает, что, возможно, позволило бы иметь динамическое содержимое внутри каждой вкладки, с другим циклом c: foreach внутри них и списком пар в компоненте поддержки, который будет содержать имена xhtml и логические значения для рендеринга (это стать немного сумасшедшим).
1 ответ
Первый вариант, условный вариант построения представления, в некоторых случаях может привести к проблемам. Например, вы не сможете полагаться на f: param в условном выражении.
Это звучит гораздо хуже для меня, чем первый вариант
Это не намного хуже. Создание набора компонентов не так уж и дорого.
Это не черно-белая вещь, но мой общий совет - не оптимизировать, если у вас действительно нет проблем с производительностью, и профилирование не подтвердило, что это узкое место (маловероятно). Придерживайтесь самого простого пути, который использует rendered
,
Для Mojarra вы можете настроить ведение журнала следующим образом:
<logger category="javax.enterprise.resource.webcontainer.jsf.timing">
<level name="DEBUG"/>
</logger>
И тогда вы точно увидите, сколько времени занимает построение представления (фаза жизненного цикла JSF Restore View) по сравнению с вашей логикой и рендерингом (другие фазы):
19: 47: 57,026 DEBUG [синхронизация] (задание по умолчанию-3) [TIMING] - [7ms]: время выполнения для фазы (включая любые PhaseListeners) -> RESTORE_VIEW 1
...
19: 47: 57,198 DEBUG [синхронизация] (задание по умолчанию-3) [TIMING] - [172ms]: время выполнения для фазы (включая любые PhaseListeners) -> RENDER_RESPONSE 6