commandButton actionListener在带有viewParam的PrimeFaces页面中不起作用

时间:2014-10-04 04:25:18

标签: jsf primefaces actionlistener viewparams

我在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()方法的执行。在页面主体中有一个p:commandButton和一个指向doTeste()的actionListener。

有我的Bean:

@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的行为方式是预期的? (每次触发时都执行该方法)

谢谢!

1 个答案:

答案 0 :(得分:1)

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

所以你可以

  1. 删除required="true"。可能是一个坏主意,因为你需要它。
  2. 使用<f:param name="id" value="#{someBean.id}"/>
  3. 将参数添加到commandButton
  4. 使用OmniFaces <o:viewParam>
  5. 有更多技术性解释here