JSF2 preRenderComponent is called always when f:ajax is executed
Asked Answered
D

2

5

I have an JSF page backed by NewsBean.java which has <f:event type="preRenderComponent" listener="#{newsBean.init}" /> as bean initializer.

There is a button at the bottom of the page for sending comments which has: <f:ajax event="click" execute="@form" render="@form" listener="#{newsBean.sendComment}" /> and is surrounded by an <h:form>. When button is clicked, NewsBean.init() is always called.

My bean scope is view. Is this a valid behavior (calling always init())? How can I prevent always calling init()?

Dinothere answered 19/12, 2011 at 8:17 Comment(0)
I
11

A preRender listener is always invoked on pre render event, regardless of if it's an initial request or a postback request. Every single request has a render response phase, regardless of if it's a normal request or ajax request. So this behaviour is by specification. You need to check yourself in the listener method if it's a postback request or not by checking FacesContext#isPostback().

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

The <f:event type="preRenderXxx"> (where Xxx can be View or Component) is by the way in essence a "workaround approach" for the functional requirement of being able to invoke a bean action method after the view parameters are been processed on the initial request. In the upcoming JSF 2.2 a new <f:viewAction> tag will be introduced which should do exactly the job as intented:

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

This tag supports an onPostback attribute which already defaults to false:

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

JSF 2.2 will be released the first quart of 2012. Snapshot releases of JSF 2.2 are currently already available.

Irrefutable answered 19/12, 2011 at 12:5 Comment(1)
Thanks BalusC. Perfect answer, as always.Dinothere
C
0

I guess your <f:event> tag is put inside the <h:form> tag. Hence, when you click the ajax button, it re-render the whole <h:form> component which results in the preRenderComponent event being triggered again.

I think what you should use is PreRenderViewEvent.

Commission answered 19/12, 2011 at 9:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.