Сблъсках се с проблем с PrimeFaces - помислете за формата с SelectOneMenu
, поставена вътре в Inplace
. До Inplace имаме CommandButton
, което е предназначено да нулира стойността на 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:
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);
}
}
Следният сценарий работи добре:
- Щракнете върху годината, за да покажете действителната
SelectOneMenu
- Изберете различна година (напр. 2013 г.)
- Потвърдете избора си, като щракнете върху бутона "проверка".
Ако обаче се опитам да щракна върху бутона „Нулиране на годината“, методът setYear
се извиква с оригиналната година като параметър точно преди да се извика resetYear
. Ето какво мога да видя в конзолата:
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 и няма причина да го стартирате за първоначалната стойност и след това отново за новата стойност.
Ако използвам стандартния CommandButton
вместо предоставения от PrimeFaces, изглежда, че работи правилно:
<h:commandButton id="btnResetYear" value="Reset year" rendered="#{testBean.year lt 2015}">
<f:ajax listener="#{testBean.resetYear}" render="myform" />
</h:commandButton>
Щракването върху стандартния бутон ще даде очаквания резултат:
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 ли е или съм направил нещо нередно? Има ли начин да настроя CommandButton на PF да се държи както е описано по-горе, т.е. да не задейства метода setYear
със стар параметър, предаден или трябва да се придържам към "стандартния" CommandButton
?
Експериментирах със задаване на immediate="true"
на CommandButton
и наистина първо пропусна първоначалната настройка на стойността, но SelectOneMenu
не взе под внимание новата стойност, без значение какво поставих в атрибута update
на бутона - все още показваше първоначалната стойност .
Примерът беше изпълнен с помощта на следното:
- Java 1.8 (jdk1.8.0_51 - 64 бита)
- PrimeFaces 5.2
- WildFly 8.2.0 (тестван също с JBoss 7.1)
Всяка идея е повече от добре дошла.