【问题标题】:commandButton actionListener is not working in PrimeFaces page with viewParamcommandButton actionListener 在带有 viewParam 的 PrimeFaces 页面中不起作用
【发布时间】:2014-11-29 03:23:29
【问题描述】:

我在 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。

这是我的豆子:

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

谢谢!

【问题讨论】:

标签: jsf primefaces actionlistener viewparams


【解决方案1】:

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

所以你可以

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

还有更技术性的解释here

【讨论】:

  • 消息显示验证错误,需要值。但是我没有改页面,视图范围一定不会丢失吧?
  • 这种行为只发生在 PrimeFaces 上。这是一个错误吗?
  • 不,它应该是同一个bean,您可以通过打印登录构造函数来完全确定,但如果您使用的是javax.faces.view.ViewScoped,它是一样的。正如 BalusC 所说,“ 在每个 HTTP 请求上运行,也在回发上”,这就是问题所在。是的,我会说这是一个有一天会修复的错误,现在您只需将参数添加到 p:commandButton。 h:commandButton 不要使用 ajax 也许这就是它起作用的原因
  • 我发现很多帖子都提到了类似的东西,其中最涉及组件中的ajax。我认为这是一个严重的问题。并非所有事情都可以轻松克服。
  • @RobinsonRK IMO 这不是问题,看起来您并没有试图了解如何解决问题。 BalusC 在重复的 Q/A 中非常明确:将&lt;f:viewParam&gt; 中设置的参数作为UICommands 中的参数传递(例如&lt;p:commandButton&gt;)或使用适合您所需行为的OmniFaces 中的&lt;o:viewParam&gt;。您可以选择其中一种解决方案,或者继续抱怨 JSF 的工作原理。
猜你喜欢
  • 2015-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 2013-12-31
相关资源
最近更新 更多