JSF2 preRenderComponent вызывается всегда, когда выполняется f: ajax - PullRequest
4 голосов
/ 19 декабря 2011

У меня есть страница JSF, поддерживаемая NewsBean.java, в которой инициализатором компонента является <f:event type="preRenderComponent" listener="#{newsBean.init}" />.

В нижней части страницы есть кнопка для отправки комментариев, которая имеет: <f:ajax event="click" execute="@form" render="@form" listener="#{newsBean.sendComment}" /> и окруженана <h:form>.Когда нажимается кнопка, всегда вызывается NewsBean.init().

Моя область действия - просмотр.Это правильное поведение (вызывая всегда init ())?Как я могу запретить всегда звонить init()?

Ответы [ 2 ]

9 голосов
/ 19 декабря 2011
Слушатель

A preRender всегда вызывается при событии предварительного рендеринга, независимо от того, является ли это первоначальным запросом или запросом обратной передачи. Каждый запрос имеет фазу ответа рендеринга, независимо от того, является ли это обычный запрос или запрос ajax. Так что это поведение по спецификации. Вы должны проверить себя в методе слушателя, если это запрос обратной передачи или нет, отметив FacesContext#isPostback().

public void sendComment() {
    if (!FacesContext.getCurrentInstance().isPostback()) {
        // ...
    }
}

<f:event type="preRenderXxx"> (где Xxx может быть View или Component) - это, по сути, "обходной подход" для функционального требования возможности вызывать метод действия компонента после параметров просмотра. были обработаны по первому запросу. В грядущем JSF 2.2 будет введен новый тег <f:viewAction>, который должен выполнять именно ту работу, для которой он предназначен:

<f:viewAction action="#{newsBean.sendComment}" />

Этот тег поддерживает атрибут onPostback, который по умолчанию уже равен false:

<f:viewAction action="#{newsBean.sendComment}" onPostback="false" />

JSF 2.2 выйдет в первом квартале 2012 года. В настоящий момент уже доступны снэпшоты JSF 2.2.

0 голосов
/ 19 декабря 2011

Полагаю, ваш тег <f:event> находится внутри тега <h:form>.Следовательно, когда вы нажимаете кнопку ajax, он повторно отображает весь компонент <h:form>, что приводит к повторному запуску события preRenderComponent.

Я думаю, вам следует использовать PreRenderViewEvent .

...