jsf命令按钮动作不工作ajax

时间:2013-05-06 10:43:43

标签: java jsf jsf-2

我有这个页面,我有两个表格。第二种形式由ajax加载(呈现)。问题是,当按下下一个表单的按钮时,页面只是重新加载,而不是实际调用'action'中指定的方法。

XHTML

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
                template="./../WEB-INF/employeeTemplate.xhtml"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns="http://www.w3.org/1999/xhtml">

    <ui:define name="content">
        finding user ...
        <h:form id="mainForm">
            <h:inputText id="userId" value="#{eFindUser.userId}" />
            <h:commandButton value="Render!" action="#{eFindUser.findUser}" >
                <f:ajax event="action" execute="userId" render="@all" />
            </h:commandButton>
        </h:form>        

        <h:panelGroup id="result">
            <h:panelGroup layout="block" rendered="#{eFindUser.notFound}" style="color:red">
                User not found
            </h:panelGroup>

            <h:form>
                <h:panelGroup layout="block" rendered="#{eFindUser.responseRendered}" >

                    <h:inputHidden value="#{eFindUser.user}" />
                    <table>
                        <tr>
                            <td>Name</td> <td>#{eFindUser.user.name}</td>
                        </tr>
                        <tr>
                            <td>Balance:</td> <td>#{eFindUser.user.account.balance}</td>
                        </tr>

                        <tr>
                            <td><h:commandButton value="update balance" action="#{eFindUser.process()}" /></td>
                        </tr>
                    </table>


                </h:panelGroup>
            </h:form>                        
        </h:panelGroup>



    </ui:define>

</ui:composition>

支持bean

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package backingbeans;

import entities.User;
import java.io.Serializable;
import java.util.Random;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.inject.Inject;
import javax.validation.constraints.NotNull;
import stateless.EmployeeFacade;

/**
 *
 * @author Martin
 */
    @ManagedBean(name="eFindUser")
    @ViewScoped
    public class EFindUserManagedBean implements Serializable{
        private static final long serialVersionUID = -7106162864352727534L;
        private boolean responseRendered = false;
        private boolean notFound = false;
        @NotNull
        private Long userId;
        private User user;

        @Inject
        private EUpdateBalanceManagedBean updateBalance;

        @Inject
        private EmployeeFacade employeeFacade;

        /**
         * Creates a new instance of EFindUserManagedBean
         */

        public EFindUserManagedBean() {
        }

        public void findUser() {
            if(new Random().nextDouble() < 0.3) {
                notFound = true;
                responseRendered = false;
            } else {
                notFound = false;
                responseRendered = true;
                user = employeeFacade.getUserById(3L);
            }

        }
        public boolean isResponseRendered() {
            return responseRendered;
        }

        public void setResponseRendered(boolean responseRendered) {
            this.responseRendered = responseRendered;
        }

    public boolean isNotFound() {
        return notFound;
    }

    public void setNotFound(boolean notFound) {
        this.notFound = notFound;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        System.out.println("blah");
        this.userId = userId;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        System.out.println("setting user");
        this.user = user;
    }


    public String process() {
        updateBalance.setUser(user);
        System.out.println("process");
        return "/employee/updateBalance.xhtml?faces-redirect=true";
    }

    }

当我点击第一个'渲染!' - 标记按钮时,它就像魅力一样。第二个表单已加载并准备工作。当我点击下一个“更新余额”标记的按钮时,页面只是重新加载它当然不应该。它应该重定向到“/ employee / updateBalance”。或者至少应该调用流程方法。

非常感谢

编辑:@BalusC是对的,答案在上一个问题中

2 个答案:

答案 0 :(得分:0)

罪魁祸首可以在第二种形式的<h:inputHidden>标签中找到:

<h:form>
    <h:panelGroup layout="block" rendered="#{eFindUser.responseRendered}" >
        <h:inputHidden value="#{eFindUser.user}" />
    </h:panelGroup>
</h:form>

最有可能是它的绑定值,eFindUser.user的类型为User,当您提交该表单时,JSF不知道如何使用User对象分配用户的字符串表示形式。

因此,存在转换错误,根据JSF生命周期,在这种情况下不调用action方法。此外,如果您的视图中有<h:messages>,您就会知道。

可以做的是:

  1. 将转化器分配到您的输入,例如<h:inputHidden value="#{eFindUser.user}" converter="userConverter"/>,并已实施@FacesConverter。可以找到更多详细信息here
  2. <h:inputHidden>绑定到String,以便不需要转换器:<h:inputHidden value="#{eFindUser.user.userNickname}">Integer以类似的方式。

答案 1 :(得分:0)

修改 <h:commandButton value="update balance" action="#{eFindUser.process()}" /><h:commandButton value="update balance" action="#{eFindUser.process}" /> el表达式不能包含“()”