Данные из <p: dataTable>, полученные из области флеш-памяти во время события preRenderView, теряются при выполнении разбивки на страницы или сортировки

У меня есть страница и сортировка <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>

Его данные получены из объема вспышки в @ViewScoped боб во время preRenderView событие:

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

Когда я выполняю разбиение на страницы или сортировку, данные теряются. Как это вызвано и как я могу решить это?

1 ответ

Решение

Вы, кажется, думаете, что preRenderView выполняется только один раз при создании области просмотра. Это не верно. preRenderView выполняется во время каждого HTTP-запроса непосредственно перед визуализацией представления (еще раз прочитайте имя события, теперь оно должно иметь больше смысла, верно?). Разбивка на страницы и сортировка выполняется с помощью ajax. Каждый ajax-запрос также считается HTTP-запросом. Срок действия данных Flash-области составляет всего одно перенаправление. Данные в области флэш-памяти больше не доступны для всех последующих запросов, если они еще раз явно не заданы в области действия флэш-памяти. Таким образом, в основном, ваш метод слушателя повторно вызывается при каждом запросе на разбиение на страницы и сортировке, который эффективно устанавливает detalle в null,

Избавиться от <f:event> в целом и положить @PostConstruct аннотация по методу. Таким образом, он действительно вызывается только один раз при создании области просмотра, точно так, как вы и предполагали.

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

Смотрите также:


Не имеющий отношения к конкретной проблеме, этот дизайн... немного странный. Я бы действительно посоветовался с более опытным архитектором JSF о том, как правильно выполнить конкретное функциональное требование, для которого вы, возможно, ошибочно полагали, что использование флэш-области таким образом будет правильным подходом.

Другие вопросы по тегам