Правильный способ установить свойство контроллера при использовании - PullRequest
0 голосов
/ 20 июня 2019

У меня есть большая форма, которую мне нужно повторно использовать на нескольких страницах. Итак, я решил создать
<ui:composition>, которая содержит форму и включает ее в некоторые страницы (page1.xhtml и page2.xhtml).

form.xhtml:

<ui:composition ...>
    <!-- The form goes here -->
</ui:composition>

Эта форма имеет контроллер под названием FormController.

В page1.xhtml и page2.xhtml я просто включаю форму, используя тег <ui:include>:

<ui:include src="/WEB-INF/.../form.xhtml"/>

Мне нужно инициализировать свойство в компоненте FormController, поэтому в page1.xhtml я решил установить атрибут с нужным мне идентификатором (например, 5):

<c:set var="id" scope="request" value ="5"/>

А в контроллере я просто получаю значение этого атрибута:

@PostConstruct
public init() {
    Long id = ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getAttribute("id");
    //Do some queries to the database
}

Пока не знаешь, все работает нормально. Но в page2.xhtml «инициализация» свойства bean-компонента должна выполняться после запроса ajax, поэтому я использовал следующий код:

<h:selectOneMenu ...>
    <f:selectItems ...>
    <f:ajax listener="#{otherBean.doSomething}" render="panel"/>
</h:selectOneMenu>

<h:panelGroup id="panel">
    <c:set var="id" scope="request" value ="#{otherBean.id}"/>
    <ui:include src="/WEB-INF/.../form.xhtml"/>
</h:panelGroup>

Что странно, так это то, что это работает только при первом выборе элемента в <h:selectOneMenu>. Во второй раз вызывается метод doSomething(), но панель не отображается (я не знаю почему, вы знаете, почему?), Поэтому я решил изучить следующую альтернативу, которая хорошо работает на обеих страницах, но я чувствую, что это не хорошее решение:

#{bean.init(otherBean.id)}
<ui:include src="/WEB-INF/modules/company/company.xhtml"/>

Как видите, я просто вызываю метод init (до <ui:include>) с нужным мне аргументом. В контроллере я просто устанавливаю свойство и выполняю соответствующие запросы:

public init(Long id) {
    this.id = id;
    //Do some queries
}

Что вы думаете об этом решении?

1 Ответ

0 голосов
/ 21 июня 2019

Если форма должна быть инициализирована при запуске, вы можете использовать

<f:metadata>
    <f:viewAction action="#{otherBean.initSomething('MYID2')}"/>
</f:metadata>

Если форма должна быть инициализирована действием

<h:commandButton action='#{otherBean.doSomething('MYID1')}'...>

или

<f:ajax listener="#{otherBean.doSomething('MYID')}" .../>
...