UI: включить в зависимости от viewParam
У меня есть страница, на которой я хочу включить часть страницы (в данном случае нижний колонтитул) в зависимости от значений, заданных параметром представления.
У меня есть мой ViewScoped
инициализация вспомогательного компонента на preRenderView
<f:metadata>
<f:viewParam name="racecode" value="#{displayResults.racecode}" />
<f:event type="preRenderView" listener="#{displayResults.init}" />
</f:metadata>
Это запрашивает базу данных, чтобы получить имя нижнего колонтитула, который будет включен. Затем это используется следующим образом:
<h:panelGroup id="customFooter" display="block">
<ui:include src="#{displayResults.customFooter}" />
</h:panelGroup>
Это всегда дает мне пропущенную страницу. Но если я ввожу имя страницы вручную, это работает. То же самое, если я заменю ui:include
с h:outputText
,
Я понимаю, что это как-то связано с фазами JSF и что в то время ui:include
сделано, значение еще не установлено. (чтение и лучшее понимание фаз - это что-то в моем списке TODO).
Вопрос остается. Как я могу сделать что-то в этом роде. Пусть бин использует viewParam, запрашивает базу данных и использует это значение в ui:include
?
2 ответа
@wemu уже объяснил причину. <ui:include src>
оценивается раньше init()
метод называется. Его предложил <f:phaseListener>
Решение, однако, неуклюже.
Просто используйте @ManagedProperty
/@PostConstruct
на @RequestScoped
боб.
@ManagedProperty("#{param.racecode}")
private String racecode;
@PostConstruct
public void init() {
// ...
}
Прослушиватели PreRenderView вызываются в RenderResponsePhase до того, как компоненты отображаются, НО ПОСЛЕ вызова TagHandlers. Это означает, что TagHandlers НЕ будет видеть данные, инициализированные в событии PreRenderView.
Если вы используете <ui:include value="#{myBean.myViewId}" />
для динамического переключения включения вы не можете использовать прослушиватель событий PreRenderView, чтобы установить myViewId
собственностью myBean
,
Если вам нужно сделать это, используйте <f:phaseListener>
,