我有一个很大的表单,需要在多个页面中重复使用。因此,我决定创建一个
<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
}
你对这个解决方案有什么看法?