我正在寻找有关使用JSF 2在视图之间保留bean值的最佳实践。
考虑以下情况:
*在视图A中,视图范围bean ABean被实例化并检索数据以在视图中显示
*在视图A中,您可以单击某个条目以查看视图B中的详细信息
*从视图B返回到视图A时,将显示先前由ABean检索的数据。
保留ABean检索到的数据的最佳方法是什么,以便在从视图B返回时能够再次显示它?
由于从视图B返回时创建了新的ABean实例,因此通常会再次检索数据,这不是一个选项,因为这是一个耗时的操作并导致糟糕的使用体验。
让ABean成为会话范围不是一个选项,因为如果您离开页面然后返回,将显示“缓存”数据而不是检索新数据(即,您无法确定是否由于导航而加载视图A.到页面或如果您从视图B返回。)
我正在寻找的东西显然是一个会话范围,很好地解决了这个问题(这是我们之前使用JSF 1和WebFlow时所拥有的)。不幸的是,JSF没有这个,因为我们处于portlet环境中,所以我们无法使用CDI。
有什么想法吗?
答案 0 :(得分:1)
使用带有条件渲染内容的单个视图是最简单的。
E.g。
<h:form>
<h:dataTable id="table" value="#{bean.items}" var="item" rendered="#{empty bean.item}">
<h:column>
#{item.foo}
</h:column>
<h:column>
#{item.bar}
</h:column>
<h:column>
<h:commandLink value="edit" action="#{bean.edit(item)}">
<f:ajax execute="@this" render="@form" />
</h:commandLink>
</h:column>
</h:dataTable>
<h:panelGrid id="detail" columns="3" rendered="#{not empty bean.item}">
<h:outputLabel for="foo" />
<h:inputText id="foo" value="#{bean.item.foo}" />
<h:message for="foo" />
<h:outputLabel for="bar" />
<h:inputText id="bar" value="#{bean.item.bar}" />
<h:message for="bar" />
<h:panelGroup />
<h:commandButton value="save" action="#{bean.save}">
<f:ajax execute="detail" render="@form" />
</h:commandButton>
<h:messages globalOnly="true" layout="table" />
</h:panelGrid>
</h:form>
使用以下视图作用域
private List<Item> items;
private Item item;
@EJB
private ItemService itemService;
@PostConstruct
public void init() {
items = itemService.list();
}
public void edit(Item item) {
this.item = item;
}
public void save() {
itemService.save(item);
item = null;
}
如有必要,视图部分可以分成两个<ui:include>
。如果需要,可以将bean拆分为两个bean(每个部分一个),其中详细信息将表1作为托管属性。但这不是必要的,只会使它更复杂。