0

我有一个很大的表单,需要在多个页面中重复使用。因此,我决定创建一个
<ui:composition>包含表单并将其包含在某些页面(page1.xhtml 和 page2.xhtml)中。

表单.xhtml:

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

此表单有一个名为 的控制器FormController

在 page1.xhtml 和 page2.xhtml 中,我只使用<ui:include>标签包含表单:

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

我需要在 FormController bean 中初始化一个属性,因此,在 page1.xhtml 中我决定使用我需要的 Id 设置一个属性(例如 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
}

你对这个解决方案有什么看法?

4

1 回答 1

0

如果表单必须在开始时初始化,您可以使用

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

如果表单必须由操作初始化

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

或者

<f:ajax listener="#{otherBean.doSomething('MYID')}" .../>
于 2019-06-21T06:46:26.073 回答