JSF f: событие preRenderView запускается с помощью f: ajax-вызовов и частичных рендерингов, что-то еще?
Итак, у нас есть f: event:
<f:metadata>
<f:event type="preRenderView" listener="#{dashboardBacking.loadProjectListFromDB}"/>
</f:metadata>
который запускается по желанию при начальной загрузке страницы (рендеринг).
Однако это событие preRenderView также инициируется рендерингом частичной страницы ajax, который повторно отображает группу h: panel с id projectListing, как показано ниже.
<h:commandButton action="#{mrBean.addProject}" value="Create Project"
title="Start a new project">
<f:ajax render="projectListing" />
</h:commandButton>
Я хочу, чтобы панель dashboardBacking.loadProjectListFromDB вызывалась для первоначальной рендеринга страницы, но не при частичном рендеринге ajax. Есть ли более подходящее событие или метод, который я мог бы использовать?
Ответы
Ответ 1
Другой вариант - разместить ваши функции preRenderView
в @PostConstruct
методе ViewScoped
bean. Эта логика будет выполняться, когда инициализируется bean, и вы сохраняете один и тот же экземпляр bean для всех ваших запросов ajax до тех пор, пока вы не измените представления.
Ответ 2
У меня была такая же потребность не так давно. В итоге я использовал что-то, предложенное BalusC.
В классе FacesContext есть метод, который позволяет вам узнать, имеете ли вы дело с полномасштабным запросом или частичной обработкой какого-либо рода:
FacesContext.getCurrentInstance().isPostback()
Таким образом, вы все еще можете использовать технику preRenderView и проверить, является ли она обратной передачей в слушателе. Я нашел это особенно полезным, потому что мне нужен сеанс bean, поскольку пользователю пришлось перейти на другую страницу и вернуться. Если бы я использовал view scoped beans (как было предложено выше Брайаном), я потерял бы информацию, которую я имел до перехода.
Ответ 3
Другая возможность - проверить, является ли запрос ajax одним или нет в методе preRenderView. Вы также можете выполнять нагрузку условно с учетом других факторов, например, если запрос является GET или нет, и если проверка не выполнена или нет (проверка параметров может быть неудачной на странице GET).
boolean getMethod = ((HttpServletRequest) fc.getExternalContext().getRequest()).getMethod().equals("GET") ? true : false;
boolean ajaxRequest = fc.getPartialViewContext().isAjaxRequest();
boolean validationFailed = fc.isValidationFailed();
Ответ 4
Здесь описывается способ "нового возраста":
http://www.coderanch.com/t/509746/JSF/java/duplicate-call-preRenderView-event#2634752
Ответ 5
Вы можете попробовать подключить прослушиватель событий preRenderView к отдельному компоненту, а не к странице. Выберите компонент, который не отображается во время запроса Ajax.
Ответ 6
Одна небольшая проблема заключается в том, что параметры представления не были установлены при вызове метода @PostConstruct, поэтому я должен был явно их явно:
FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("theParam");
Ответ 7
update: на самом деле, я закончил работу с @PostConstruct, ее намного чище.
У меня была точно такая же проблема и с поддержкой . А именно, я зарегистрировал метод event-listener в области поддержки bean с поддержкой сеанса, который был зарегистрирован в preRenderView. Но я обнаружил, что он также был запущен на некоторых операциях сортировки Ajax на компоненте dataTable PrimeFaces 3. Итак, что я закончил делать, это использовать переменную экземпляра boolean в поддержке bean для сеанса, чтобы убедиться, что тело метода event-listener выполняется только в первый раз (логическое значение действует как флаг). Я уверен, что это довольно наивно и, вероятно, нарушено в некоторых случаях, поэтому мне было бы интересно узнать, почему и как этот упрощенный подход может потерпеть неудачу.