我正在寻找有关使用JSF 2在视图之间保留Bean值的最佳实践。
请考虑以下情形:
*在视图A中,实例化了作用域范围的bean ABean,并检索了要在视图中显示的数据。
*在视图A中,您可以单击条目以在视图B中查看其详细信息。
*从视图B返回到视图A时,将显示先前由ABean检索的数据。
保留ABean检索到的数据以便从视图B返回时能够再次显示的最佳方法是什么?
再次检索数据通常不会发生,因为从视图B返回时会创建一个新的ABean实例,因此通常不会进行检索,因为这是一项耗时的操作,并且会导致不良的使用体验。
不允许将ABean限制在会话范围内,因为如果您离开页面然后返回,则将显示“缓存”数据,而不是检索新数据(即,您无法确定是否由于导航而加载视图A返回页面,或者如果您要从视图B返回)。
我正在寻找的显然是一个对话范围,可以很好地解决此问题(这是我们以前使用JSF 1和WebFlow时所拥有的)。不幸的是,JSF没有该功能,并且由于我们处于Portlet环境中,因此无法使用CDI。
有什么想法吗?
最佳答案
使用单个视图和有条件渲染的内容是最简单的。
例如。
<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>
与以下视图范围的bean
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作为托管属性。但这不是必需的,只会使它更加复杂。