我正在寻找有关使用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作为托管属性。但这不是必需的,只会使它更加复杂。

08-28 22:30