5

我有一个由 NewsBean.java 支持的 JSF 页面,它具有<f:event type="preRenderComponent" listener="#{newsBean.init}" />bean 初始化程序。

页面底部有一个用于发送评论的按钮,其中包含: <f:ajax event="click" execute="@form" render="@form" listener="#{newsBean.sendComment}" /><h:form>。当按钮被点击时,NewsBean.init()总是被调用。

我的 bean 范围是视图。这是一个有效的行为(总是调用 init())吗?我怎样才能防止总是打电话init()

4

2 回答 2

11

preRender无论是初始请求还是回发请求,始终都会在预渲染事件上调用侦听器。每个请求都有一个渲染响应阶段,无论它是普通请求还是 ajax 请求。所以这种行为是规范的。您需要在侦听器方法中检查自己是否是回发请求,方法是检查FacesContext#isPostback().

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

顺便说一下,<f:event type="preRenderXxx">(其中Xxx可以是ViewComponent)本质上是一种“解决方法”,用于在初始请求上处理视图参数后能够调用 bean 操作方法的功能要求。在即将到来的 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 的快照版本目前已经可用。

于 2011-12-19T12:05:49.727 回答
0

我猜你的<f:event>标签放在<h:form>标签里面。因此,当您单击 ajax 按钮时,它会重新渲染整个<h:form>组件,从而再次触发 preRenderComponent 事件。

我认为您应该使用的是PreRenderViewEvent

于 2011-12-19T09:19:46.250 回答