在预渲染视图事件期间从闪存范围获取的来自<p:dataTable>的数据在执行分页或排序时丢失



我有一个可分页和可排序的<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>

preRenderView事件期间,其数据从闪存示波器获取到@ViewScoped Bean 中:

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

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

您似乎认为在创建视图范围期间仅执行一次preRenderView。这是错误的。preRenderView在每个 HTTP 请求期间执行,就在呈现视图之前(再次读取事件名称,现在应该更有意义了,对吧?分页和排序由 ajax 执行。每个 ajax 请求也被视为 HTTP 请求。Flash 范围的数据的生存期只有一个重定向。Flash 范围数据不再可用于所有后续请求,除非再次在 flasch 作用域中显式设置。所以基本上,你的侦听器方法在每个分页和排序请求上都会被重新调用,从而有效地将detalle设置为null

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

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

另请参阅:

  • 何时使用 f:viewAction/preRenderView 与 PostConstruct?

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

相关内容

  • 没有找到相关文章

最新更新