Primefaces - commandButton不起作用

16

我正在使用commandButton时遇到问题,仅当类型为submit时才有效。请问是否有解决方法?以下代码非常简单,旨在说明我所需要的内容。test()方法没有被执行,而runSubmit方法已成功执行。

我需要在不进行提交的情况下执行test方法,因为原始页面具有在提交期间执行的验证,而test()方法必须在提交之前作为预操作执行。

我正在使用PrimeFaces 4.0、JDK 7、Tomcat 6和JSF 2.0(Apache),不过我认为Mojarra也会发生这种情况。

    SESSION:

package com.andre.bean;

public class AndreBean {

public void runSubmit() {
System.out.println("Submit executed");
}

public String test() {
System.out.println("Not submit executed");
return "true";
}

}

XHTML

<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:p="http://primefaces.org/ui">

<h:head> 
</h:head>

<h:form id="test">
<p:commandButton id="ns" value="not submit" type="button" action="#{andreBean.test}" ajax="false"></p:commandButton>
<p:commandButton id="s" value="submit" action="#{andreBean.runSubmit}"></p:commandButton>

</h:form> 

</html>
非常感谢 Andre

2
尝试使用actionListener="#{andreBean.test()}"和process="@this :test"。 - Thangnv
谢谢您的回复,我刚试了一下,但是没有成功,结果和之前一样。然而,当在测试方法中使用括号时,我遇到了解析错误,只有使用"andreBean.test"才有效。我读到了一些关于EL的限制的内容,我需要在这个项目中使用Tomcat 6版本,因为可用的EL版本只有2.1。感谢您提供的额外信息。 - Andre
如果您不想进行完整的表单提交,您将需要使用AJAX... - unwichtich
您不需要f:ajax。您可以在p:commandButton上设置ajax =“true”(这是默认设置),然后使用actionListener=“#{andreBean.test}”。 - unwichtich
只有当按钮类型为submit时才有效(这也是默认值),使用type="button"则无效。我刚刚运行了相同的测试,但现在使用的是tomcat 7和JSF 2.2,在那个f:ajax execute中工作了,在方法“#{andreBean.test()}”中使用括号。但Tomcat 7不是我的要求...看起来JSF 2.0中存在一些错误。仍在考虑使用tomcat 6和JSF 2.0修复它的方法。 - Andre
显示剩余2条评论
3个回答

37

发生了什么?

您得到的是正确的行为。使用 type="button"的 PrimeFaces 按钮的工作方式与基本 HTML 中的按钮相同 - 它不会导致任何请求。正如PrimeFaces 用户指南所述:

推送按钮用于执行自定义 JavaScript,而不会引起ajax / 非ajax请求。要创建推送按钮,请将类型设置为“button”。

<p:commandButton type="button" value="Alert" onclick="alert('Prime')" />
如果您想要与bean“交谈”,则需要使用type="submit"(在p:commandButton中默认值)。 然而……与HTML中提交按钮的行为相反,在PrimeFaces中,这样的提交不会强制重定向到新页面,而是所有通信都将由底层的AJAX请求处理。
因此,只有您的第二个按钮将执行bean的方法:
<p:commandButton id="s" value="submit" action="#{andreBean.runSubmit}" />

您想要获得的是什么?

如果您不想将整个表单发送到bean,可以使用p:commandButton的“process”属性限制要处理的组件范围:

<h:form id="test">
    <p:inputText value="#{andreBean.value}"/>
    <p:commandButton id="s" value="submit" action="#{andreBean.runSubmit}" process="@this" />
</h:form>

使用以下Bean,您将看到差异:

public class AndreBean {

    private String value;

    public void runSubmit() {
        System.out.println("Submit executed");
    }

    public String getValue() {
        System.out.println("getValue");
        return value;
    }

    public void setValue(String value) {
        System.out.println("setValue: " + value);
        this.value = value;
    }

}

如果在控制台中不限制执行的组件,你将获得:

getValue

setValue: foobar

Submit executed

只有使用process="@this"的组件,你将仅得到:

Submit executed

希望能帮到你。


2
嗨,感谢您的评论。我已经使用此链接[link](http://forum.primefaces.org/viewtopic.php?f=3&t=34788)中的建议解决了我的问题,其中<p:commandButton immediate =“true”对我有用。非常感谢。 - Andre
我遇到了类似的问题,使用process标签解决了。一开始它被设置为@this,但后来我添加了所有组件的ID,所以它看起来像这样: process=@this, componentId1, componentId2 这个改变对我很有效,而且我没有添加immediate=true标志。 - Athar

15

有时候,解决方案就是简单地添加 immediate="true",它会改变JSF生命周期中触发bean操作的时间点。


2
它能够工作是因为您正在触发一些验证,只要您在代码中没有放置任何p:messages,就看不到这些验证。现在,当您添加了immediate=true,您将绕过验证并进行提交。 - user831170

-4
请检查您与bean的绑定。
bean字段应为String或非基本类型。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接