f:setPropertyActionListener inside ui:repeat 和 accordion 的奇怪行为
Strange bevavior of f:setPropertyActionListener inside ui:repeat and accordion
在一个 jsf/primefaces(版本 6.2)项目中,我有这段代码可以在手风琴中显示记录列表。
所有记录都正确显示。
在 ui:repeat
中,我有一个 p:commandButton
可以使用 f:setPropertyActionListener
保存一些文本片段 (fragmt)。
我还实现了第二个 f:setPropertyActionListener
来获取对象 (sRes
)。这个工作正常。
但是 currentFrag
变量总是填充了最后一个手风琴的文本片段。
<h:form id="accord" >
<p:accordionPanel value="#{myBean.lucSearchResults}" var="sRes" multiple="true">
<p:tab title="#{sRes.score}">
<ui:repeat value="#{sRes.frags}" var="fragmt">
<h:panelGrid columns="2" cellpadding="10">
<h:panelGrid columns="1" cellpadding="10">
<h:outputText value="#{fragmt}" escape="false"/>
<hr/>
</h:panelGrid>
<h:panelGrid columns="1" cellpadding="10">
<p:commandButton action="#{myBean.saveFrag}" value="Save" >
<f:setPropertyActionListener value="#{sRes}" target="#{myBean.currentSearchResult}" />
<f:setPropertyActionListener value="#{fragmt}" target="#{myBean.currentFrag}" />
</p:commandButton>
</h:panelGrid>
</h:panelGrid>
</ui:repeat>
</p:tab>
</p:accordionPanel>
</h:form>
我在 JSF 和 Java 方面有着长期的经验。对于这种奇怪的行为,我没有任何解释。
非常感谢有关此问题的任何帮助或指示。
我可以使用 Primefaces 7.0、Mojarra 2.3.3、JVM 1.8 重现此内容。0_152-b16、Apache Tomcat 9.0.21、Openwebbeans 2.0.7 使用此示例:
<h:form id="frm">
<p:accordionPanel id="accordion" value="#{myBean.cats}" var="cat"
multiple="true">
<p:tab id="tab" title="#{cat.name}">
<ui:repeat var="kid" value="#{cat.kitten}">
<h:panelGroup id="group">
<p:commandButton id="cmdSubmit" action="#{myBean.doSomething()}"
value="submit #{cat.name} - #{kid.name} " process="@form"
update=":frm:output">
<f:setPropertyActionListener value="#{cat}"
target="#{myBean.cat}" />
<f:setPropertyActionListener value="#{kid}"
target="#{myBean.kid}" />
</p:commandButton>
</h:panelGroup>
</ui:repeat>
</p:tab>
</p:accordionPanel>
<h:outputText id="output"
value="#{myBean.cat.name} - #{myBean.kid.name}" />
</h:form>
这是我的豆子:
package my.package;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
@Named
@ViewScoped
public class MyBean implements Serializable {
private static final long serialVersionUID = 43L;
private List<Cat> cats;
private Cat cat;
private Cat kid;
@PostConstruct
public void init() {
cats = new ArrayList<>();
for (int i = 0; i < 10; i++) {
final Cat cat = new Cat();
cats.add(cat);
cat.setName(String.valueOf(i));
cat.setKitten(new ArrayList<>());
for (int j = 0; j < 5; j++) {
final Cat kid = new Cat();
kid.setName(i + "." + j);
cat.getKitten().add(kid);
}
}
}
public void doSomething() {
System.err.println(cat.getName() + " / " + kid.getName());
}
// getters & setters ...
public static class Cat {
private String name;
private List<Cat> kitten;
// getters & setters ...
}
}
当击中例如命令按钮显示为“5 - 5.4”,输出为“5 - 9.4”:
将 p:accordion/p:tab 替换为 ui:repeat 时,此示例按预期工作。这表明它与 primefaces 动态选项卡有关 并且可能值得提交错误报告。
当用 process="@this"
或 process="group"
替换 process="@form"
时,它也按预期工作并输出按下按钮的正确标签。
更好的解决方法 是在 tabView/accordion/dataTable 和不同的 ui:repeat
实现之间使用 p:repeat
component implemented to solve known incompatibilities。
在一个 jsf/primefaces(版本 6.2)项目中,我有这段代码可以在手风琴中显示记录列表。
所有记录都正确显示。
在 ui:repeat
中,我有一个 p:commandButton
可以使用 f:setPropertyActionListener
保存一些文本片段 (fragmt)。
我还实现了第二个 f:setPropertyActionListener
来获取对象 (sRes
)。这个工作正常。
但是 currentFrag
变量总是填充了最后一个手风琴的文本片段。
<h:form id="accord" >
<p:accordionPanel value="#{myBean.lucSearchResults}" var="sRes" multiple="true">
<p:tab title="#{sRes.score}">
<ui:repeat value="#{sRes.frags}" var="fragmt">
<h:panelGrid columns="2" cellpadding="10">
<h:panelGrid columns="1" cellpadding="10">
<h:outputText value="#{fragmt}" escape="false"/>
<hr/>
</h:panelGrid>
<h:panelGrid columns="1" cellpadding="10">
<p:commandButton action="#{myBean.saveFrag}" value="Save" >
<f:setPropertyActionListener value="#{sRes}" target="#{myBean.currentSearchResult}" />
<f:setPropertyActionListener value="#{fragmt}" target="#{myBean.currentFrag}" />
</p:commandButton>
</h:panelGrid>
</h:panelGrid>
</ui:repeat>
</p:tab>
</p:accordionPanel>
</h:form>
我在 JSF 和 Java 方面有着长期的经验。对于这种奇怪的行为,我没有任何解释。
非常感谢有关此问题的任何帮助或指示。
我可以使用 Primefaces 7.0、Mojarra 2.3.3、JVM 1.8 重现此内容。0_152-b16、Apache Tomcat 9.0.21、Openwebbeans 2.0.7 使用此示例:
<h:form id="frm">
<p:accordionPanel id="accordion" value="#{myBean.cats}" var="cat"
multiple="true">
<p:tab id="tab" title="#{cat.name}">
<ui:repeat var="kid" value="#{cat.kitten}">
<h:panelGroup id="group">
<p:commandButton id="cmdSubmit" action="#{myBean.doSomething()}"
value="submit #{cat.name} - #{kid.name} " process="@form"
update=":frm:output">
<f:setPropertyActionListener value="#{cat}"
target="#{myBean.cat}" />
<f:setPropertyActionListener value="#{kid}"
target="#{myBean.kid}" />
</p:commandButton>
</h:panelGroup>
</ui:repeat>
</p:tab>
</p:accordionPanel>
<h:outputText id="output"
value="#{myBean.cat.name} - #{myBean.kid.name}" />
</h:form>
这是我的豆子:
package my.package;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
@Named
@ViewScoped
public class MyBean implements Serializable {
private static final long serialVersionUID = 43L;
private List<Cat> cats;
private Cat cat;
private Cat kid;
@PostConstruct
public void init() {
cats = new ArrayList<>();
for (int i = 0; i < 10; i++) {
final Cat cat = new Cat();
cats.add(cat);
cat.setName(String.valueOf(i));
cat.setKitten(new ArrayList<>());
for (int j = 0; j < 5; j++) {
final Cat kid = new Cat();
kid.setName(i + "." + j);
cat.getKitten().add(kid);
}
}
}
public void doSomething() {
System.err.println(cat.getName() + " / " + kid.getName());
}
// getters & setters ...
public static class Cat {
private String name;
private List<Cat> kitten;
// getters & setters ...
}
}
当击中例如命令按钮显示为“5 - 5.4”,输出为“5 - 9.4”:
将 p:accordion/p:tab 替换为 ui:repeat 时,此示例按预期工作。这表明它与 primefaces 动态选项卡有关 并且可能值得提交错误报告。
当用 process="@this"
或 process="group"
替换 process="@form"
时,它也按预期工作并输出按下按钮的正确标签。
更好的解决方法 是在 tabView/accordion/dataTable 和不同的 ui:repeat
实现之间使用 p:repeat
component implemented to solve known incompatibilities。