-1

我在 JSF/PrimeFaces 中发现了一个奇怪的行为,并请求您帮助理解和解决它。commandButton 中的 actionListener 方法只执行一次。

语境化:

我在我的项目的起始页中放了一个链接到第二页,呈现如下:

http://localhost:8080/MeusTestes-war/faces/somepage.xhtml?id=1

请注意,查询字符串发送了一个参数。

somepage.xhtml:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:p="http://primefaces.org/ui">
    <h:head>
        <title>Facelet Title</title>
    </h:head>

    <f:metadata>
        <f:viewParam name="id" value="#{someBean.id}" required="true" />
        <f:viewAction action="#{someBean.init}" />
    </f:metadata>

    <h:body>
        <h:form id="form1">
            <p:commandButton id="teste1" 
                             value="Teste" 
                             actionListener="#{someBean.doTeste}" />
        </h:form>
    </h:body>
</html>

如您所见,它非常简单。请注意,有一个元数据部分进行参数接收和 init() 方法的执行。在页面正文中有 ap:commandButton 和一个指向 doTeste() 的 actionListener。

有我的豆:

@Named(value = "someBean")
@ViewScoped
public class SomeBean implements Serializable {

    private int id;

    public SomeBean() {
    }

    public int getId() { return id; }
    public void setId(int id) { this.id = id; }

    public void init() {
        System.out.println("init " + id);
    }

    public void doTeste(ActionEvent actionEvent) {
        System.out.println("doTeste " + id);
    }

}

好吧,现在神秘的行为:

1) 加载页面时,如预期的那样,init() 方法会显示一条消息,其中包含 viewParam 获取的正确属性值。2) 触发按钮,正如预期的那样,doTeste() 方法显示一条具有正确属性值的消息。但是,3)再次触发按钮,没有任何反应!

其他事实:

如果我删除元数据部分,doTeste() 方法的执行次数与单击按钮的次数一样多,这是应该发生的。但是很明显,该属性没有被初始化。

如果我将按钮定义从 p:commandButton 切换到 h:commandButton,doTeste() 方法将按预期执行并且属性被初始化。但我失去了 PrimeFaces 模式。

我的问题:

如何让 PrimeFaces 中的 commandButton actionListener 表现得符合预期?(每次触发时执行该方法)

谢谢!

4

1 回答 1

1

如果您出于测试目的添加 a<p:growl id="msgs"/>并添加update="msgs"到按钮,您将看到后续请求的验证失败(因为在required="true"viewParam)。

所以你可以

  1. 删除required="true". 可能是个坏主意,因为您需要它。
  2. 将参数添加到命令按钮<f:param name="id" value="#{someBean.id}"/>
  3. 使用 OmniFaces <o:viewParam>

这里有更技术性的解释。

于 2014-10-04T08:22:33.117 回答