1

我有一个可分页和可排序的<p:dataTable>

<p:dataTable var="item" value="#{reporteIngresosPorExtranetController.detalle}"
    paginator="true" rows="10" paginatorPosition="bottom" rowsPerPageTemplate="5,10,15"
    paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}">
    <p:column sortBy="#{item.user}" headerText="USUARIO:">
        <h:outputText value="#{item.user}" />
    </p:column>
    ...
</p:dataTable>

它的数据是在事件期间从 flash 作用域中获取到一个@ViewScopedbean 中的preRenderView

<f:event type="preRenderView" listener="#{reporteIngresosPorExtranetController.cargarDatos}" />
public void cargarDatos() {
    detalle = (List<Map<String, Object>>) FacesUtils.flashScope().get("RIE_detalle");
}

当我执行分页或排序时,数据会丢失。这是如何引起的,我该如何解决?

4

1 回答 1

0

您似乎认为preRenderView在创建视图范围期间只执行一次。这是错误的。在呈现视图之前的每个preRenderViewHTTP 请求期间都会执行(再次读取事件名称,它现在应该更有意义,对吧?)。分页和排序由ajax执行。每个 ajax 请求也被视为一个 HTTP 请求。Flash 范围数据的生命周期恰好是一个重定向。除非再次在 flasch 范围内明确设置,否则所有后续请求都不再提供 Flash 范围的数据。因此,基本上,您的侦听器方法会在每个有效设置为.detallenull

<f:event>完全摆脱它并@PostConstruct在方法上添加注释。这样,它实际上只在创建视图范围期间调用一次,完全符合您的意图。

@PostConstruct
public void cargarDatos() {
    detalle = (List<Map<String, Object>>) FacesUtils.flashScope().get("RIE_detalle");
}

也可以看看:


与具体问题无关,这种设计……有点奇怪。我真的会咨询一位更有经验的 JSF 架构师,了解如何正确实现具体的功能需求,您可能错误地认为以这种方式使用闪存范围是正确的方法。

于 2013-11-07T16:40:56.923 回答