JSF f: событие preRenderView запускается вызовами f: ajax и частичным рендерингом, что-то еще? - PullRequest
25 голосов
/ 14 мая 2010

Итак, у нас есть событие f:

   <f:metadata>
    <f:event type="preRenderView" listener="#{dashboardBacking.loadProjectListFromDB}"/>
   </f:metadata>

Который запускается по желанию при начальной загрузке страницы (рендеринг).

Однако это событие preRenderView также инициируется частичным рендерингом страницы ajax, который повторно отображает h: panelgroup с id projectListing, как показано ниже.

<h:commandButton action="#{mrBean.addProject}" value="Create Project"
                                     title="Start a new project">
   <f:ajax render="projectListing" />
</h:commandButton>

Я хочу, чтобы dashboardBacking.loadProjectListFromDB вызывался только для начального рендеринга страницы, но не при частичном рендеринге ajax. Есть ли более подходящее событие или метод, который я мог бы использовать?

Ответы [ 7 ]

31 голосов
/ 15 октября 2011

У меня была такая же потребность не так давно. В итоге я использовал что-то, предложенное BalusC .

В классе FacesContext есть метод, который позволяет узнать, имеете ли вы дело с полным запросом или какой-то частичной обработкой:

FacesContext.getCurrentInstance().isPostback()

Таким образом, вы все еще можете использовать технику preRenderView и проверить, является ли это обратной передачей в слушателе. Я нашел это особенно полезным, потому что мне был нужен сессионный компонент, поскольку пользователю приходилось переходить на другую страницу и возвращаться. Если бы я использовал bean-объекты видимости (как предложено выше Брайаном), я бы потерял информацию, которую имел, прежде чем уйти.

11 голосов
/ 18 мая 2010

Другой вариант - поместить вашу preRenderView функциональность в @PostConstruct метод управляемого ViewScoped bean-компонента. Эта логика будет выполняться при инициализации bean-компонента, и вы будете поддерживать один и тот же экземпляр bean-компонента для всех ваших запросов ajax, пока вы не измените представления.

7 голосов
/ 15 ноября 2010

Другая возможность - проверить, является ли запрос ajax или нет в методе preRenderView. Вы также можете выполнить загрузку условно с учетом других факторов, таких как, если запрос является GET или нет, и если проверка не удалась или нет (проверка параметров просмотра может завершиться неудачей на странице GET).

boolean getMethod = ((HttpServletRequest) fc.getExternalContext().getRequest()).getMethod().equals("GET") ? true : false;
boolean ajaxRequest = fc.getPartialViewContext().isAjaxRequest();
boolean validationFailed = fc.isValidationFailed();
2 голосов
/ 28 апреля 2012

Способ решения этой проблемы описан здесь:

http://www.coderanch.com/t/509746/JSF/java/duplicate-call-preRenderView-event#2634752

1 голос
/ 18 мая 2010

Вы можете попробовать подключить прослушиватель событий preRenderView к отдельному компоненту, а не к странице. Выберите компонент, который не отображается во время запроса Ajax.

0 голосов
/ 19 июля 2012

обновление : на самом деле я закончил с @PostConstruct, он намного чище.

У меня была точно такая же проблема сегодня с компонентом поддержки сессионной области. А именно, я зарегистрировал метод прослушивателя событий для бина с заданной сессионной областью, который был зарегистрирован в preRenderView. Но я обнаружил, что он также запускался при некоторых операциях сортировки Ajax в компоненте PrimeTaces 3 dataTable. Итак, в конечном итоге я использовал логическую переменную экземпляра на бэк-бине в области сеанса, чтобы убедиться, что тело метода прослушивателя событий выполняется только в первый раз (логическое значение действует как флаг). Я уверен, что в некоторых случаях это довольно наивно и, вероятно, нарушается, поэтому мне было бы интересно узнать, почему и как этот упрощенный подход может потерпеть неудачу.

0 голосов
/ 08 февраля 2011

Одна небольшая проблема заключается в том, что параметры представления не были установлены при вызове метода @PostConstruct, поэтому мне пришлось получить их явно:

FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("theParam");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...