单击p:commandButton会使p:selectOneMenu的值被设置两次 [英] Clicking p:commandButton causes the value of p:selectOneMenu being set twice

查看:70
本文介绍了单击p:commandButton会使p:selectOneMenu的值被设置两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了PrimeFaces的问题-考虑将 SelectOneMenu 放在 Inplace 内部的形式.在Inplace旁边,我们有一个 CommandButton ,用于重置 SelectOneMenu 的值.

I ran into an issue with PrimeFaces - consider form with SelectOneMenu being put inside of Inplace. Next to the Inplace we have a CommandButton that is meant to reset the value of the SelectOneMenu.

表单如下:

<h:form id="myform">
    <p:inplace id="inplace" editor="true">
        <p:ajax event="save" update="@(form)" />

        <f:facet name="output">
            <h:outputText value="#{testBean.year}" />
        </f:facet>

        <f:facet name="input">
            <p:selectOneMenu id="selYears" value="#{testBean.year}">
                <f:selectItem itemValue="2015" itemLabel="2015" />
                <f:selectItem itemValue="2014" itemLabel="2014" />
                <f:selectItem itemValue="2013" itemLabel="2013" />
            </p:selectOneMenu>
        </f:facet>
    </p:inplace>

    <p:commandButton id="btnResetYear" value="Reset year" rendered="#{testBean.year lt 2015}"
        action="#{testBean.resetYear()}" update="@(form)" />

</h:form>

这是TestBean:

This is the TestBean:

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean
@ViewScoped
public class TestBean {
    private int year;

    @PostConstruct
    private void init() {
        this.year = 2015;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        System.out.println("---> setYear: " + year);
        this.year = year;
        this.someMethod();
    }

    public void someMethod() {
        System.out.println("---> someMethod: " + this.year);
    }

    public void resetYear() {
        System.out.println("---> resetYear");
        this.setYear(2015);
    }
}

以下情况可以正常工作:

The following scenario works just fine:

  1. 单击年份以显示实际的 SelectOneMenu
  2. 选择不同的年份(例如2013年)
  3. 通过单击检查"按钮确认选择

但是,如果我尝试单击重置年份"按钮,则会在调用 resetYear 之前使用原始年份作为参数来调用方法 setYear .这是我在控制台中看到的:

However, if I try clicking the "Reset year" button, the method setYear is called with the original year as a parameter just before resetYear is called. This is what I can see in a console:

12:28:40,003 INFO  [stdout] (default task-15) ---> setYear: 2013
12:28:40,003 INFO  [stdout] (default task-15) ---> someMethod: 2013
12:28:40,004 INFO  [stdout] (default task-15) ---> resetYear
12:28:40,004 INFO  [stdout] (default task-15) ---> setYear: 2015
12:28:40,004 INFO  [stdout] (default task-15) ---> someMethod: 2015

这是我不想要的,因为 someMethod 用于从DB加载数据,没有理由先运行原始值,然后再次运行新值.

Which is what I do not want as someMethod is intended to e.g. load data from DB and there is no reason to run it for the original value and then for the new value again.

如果我使用标准的 CommandButton 而不是PrimeFaces提供的命令,它似乎可以正常工作:

If I use the standard CommandButton instead of the one provided by PrimeFaces, it seems to work properly:

<h:commandButton id="btnResetYear" value="Reset year" rendered="#{testBean.year lt 2015}">
    <f:ajax listener="#{testBean.resetYear}" render="myform" />
</h:commandButton>

单击标准按钮将得到预期的结果:

Clicking the standard button would give the expected result:

12:42:11,506 INFO  [stdout] (default task-88) ---> resetYear
12:42:11,506 INFO  [stdout] (default task-88) ---> setYear: 2015
12:42:11,506 INFO  [stdout] (default task-88) ---> someMethod: 2015

问题:

这是PrimeFaces中的错误,还是我做错了什么?有没有一种方法可以将PF的CommandButton设置为如上所述的行为,即不通过传入的旧参数触发 setYear 方法,还是我必须坚持使用标准" CommandButton ?

Is this a bug in PrimeFaces or did I do anything wrong? Is there a way to setup the PF's CommandButton to behave like described above, i.e. not to trigger the setYear method with old parameter passed in or do I have to stick with the "standard" CommandButton?

我正在尝试将 immediate ="true" 设置为 CommandButton ,确实跳过了最初的设置,但是 SelectOneMenu 不管我将按钮的 update 属性设置为什么,它都没有考虑新值-它仍显示原始值.

I was experimenting with setting immediate="true" to the CommandButton and it indeed skipped setting the original value first, but the SelectOneMenu didn't take the new value into account, no matter what I put into the button's update attribute - it was still showing the original value.

该示例使用以下代码运行:

The example was run using the following:

  • Java 1.8(jdk1.8.0_51-64位)
  • PrimeFaces 5.2
  • WildFly 8.2.0(也已通过JBoss 7.1进行了测试)

任何想法都值得欢迎.

推荐答案

再过几个小时,我发现了问题所在-PF的 CommandButton 的默认行为是处理页面上的所有内容,这与我设置 process ="@ all"

After few more hours I figured out what the problem was - the default behavior of PF's CommandButton is to process everything on the page, which is basically the same as if I set process="@all"

我通过检查 CommandButton 发送/接收的请求/响应的详细信息发现了这一点-请求标头中包含以下参数:

I found out this by checking details of the request/response sent/received by the CommandButton - there was the following parameter in the request header:

javax.faces.partial.execute = @all

因此将 process ="@ this" 设置为 CommandButton 可以达到目的,现在我可以观察到正确的行为:

So setting process="@this" to the CommandButton did the trick and I can observe the correct behavior now:

18:45:51,874 INFO  [stdout] (default task-41) ---> resetYear
18:45:51,874 INFO  [stdout] (default task-41) ---> setYear: 2015
18:45:51,874 INFO  [stdout] (default task-41) ---> someMethod: 2015

这是我的 CommandButton 的最终版本:

<p:commandButton id="btnResetYear" value="Reset year" rendered="#{testBean.year lt 2015}"
    action="#{testBean.resetYear()}" update="@(form)" process="@this" />

我希望通过在此处发布此解决方案来节省别人的时间:-)

I hope to save someone else's time by posting this solution here :-)

这篇关于单击p:commandButton会使p:selectOneMenu的值被设置两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆