JSF ajax 监听器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5040184/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 10:57:51  来源:igfitidea点击:

JSF ajax listener

ajaxjsfjsf-2

提问by Matti Lyra

I'm trying to figure out how to log out a user with an f:ajaxcall using JSF and a backing managed bean. The problem I'm having is that I can't quite figure out why the call order for the Ajax listener and the rerender of the login form.

我试图弄清楚如何f:ajax使用 JSF 和支持托管 bean通过调用注销用户。我遇到的问题是我无法弄清楚为什么 Ajax 侦听器的调用顺序和登录表单的重新呈现。

Below is the very simplified code. The basic idea of the code is this

下面是非常简化的代码。代码的基本思想是这样的

if (uid != null) {
    // show log out
} else {
    // show log in
}

I am clearly not understanding something about how the ajax listeners and the form rerender is done.

我显然不了解 ajax 侦听器和表单重新渲染是如何完成的。

The JSF page

JSF 页面

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:c="http://java.sun.com/jsp/jstl/core">
  <h:head>
    <title>Facelet Title</title>
  </h:head>
  <h:body>
    <f:view>
      <h:form id="loginForm">
        <c:choose>
          <c:when test="${userBean.uid != null}">
            <span>Hi, #{userBean.uid}</span>
            <h:commandButton value="Logout">
              <f:ajax event="click" listener="#{userBean.logout}" render="loginForm"/>
            </h:commandButton>
            </c:when>
            <c:otherwise>
            <span>User name: </span>
            <h:inputText value="#{userBean.uid}" id="uid" />
            <h:commandButton value="Login" action="#{userBean.login}" />
            </c:otherwise>
          </c:choose>
        </h:form>
      </f:view>
    </h:body>
</html>

The Bean

豆子

package test.auth;

import java.io.Serializable;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import javax.faces.event.AjaxBehaviorEvent;

@Named(value="userBean")
@SessionScoped
public class UserBean
    implements Serializable
{
    private static final long serialVersionUID = -4292770567982457272L;

    private String uid;
    /** Creates a new instance of UserBean */
    public UserBean() {
    }

    public String getUid()
    {
        return uid;
    }

    public void setUid(String uid)
    {
        this.uid = uid;
    }

    public String login () {
        return "faces/index.xhtml";
    }

    public void logout (AjaxBehaviorEvent event) {
        this.uid = null;
    }
}

The problem with the code is that when clicking logoutthe form reloads but it is still in the logged in state even though the uidhas been set to null. I've checked this with the debugger. So how do I make the render be executed AFTER the ajax listener?

代码的问题在于,当单击logout表单重新加载时,即使uid已将null. 我已经用调试器检查过了。那么如何在 ajax 侦听器之后执行渲染呢?

回答by BalusC

The JSTL tags are executed during view build time, not during view render time. At the moment JSF is reusing the view state for re-render, the JSTL tags won't be re-executed, simply because they are not there anymore.

JSTL 标记在视图构建期间执行,而不是在视图渲染期间执行。在 JSF 重用视图状态进行重新渲染时,不会重新执行 JSTL 标记,因为它们不再存在。

You want to use JSF renderedattribute instead.

您想改用 JSFrendered属性。

<h:form id="loginForm">
  <h:panelGroup rendered="#{userBean.uid != null}">
    <span>Hi, #{userBean.uid}</span>
    <h:commandButton value="Logout">
      <f:ajax event="click" listener="#{userBean.logout}" render="loginForm"/>
    </h:commandButton>
  </h:panelGroup>
  <h:panelGroup rendered="#{userBean.uid == null}">
    <span>User name: </span>
    <h:inputText value="#{userBean.uid}" id="uid" />
    <h:commandButton value="Login" action="#{userBean.login}" />
  </h:panelGroup>
</h:form>