问题
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
.
The form looks like this:
<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>
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:
- Click the year to show the actual
SelectOneMenu
- Select different year (e.g. 2013)
- Confirm the selection by clicking the "check" button
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
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.
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
QUESTION:
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
?
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 - 64bit)
- PrimeFaces 5.2
- WildFly 8.2.0 (also tested with JBoss 7.1)
Any idea is more than welcome.
回答1:
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"
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
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
This is the final version of my 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 :-)
来源:https://stackoverflow.com/questions/32295806/clicking-pcommandbutton-causes-the-value-of-pselectonemenu-being-set-twice