以下是我的问题的测试用例:
@ManagedBean
@ViewScoped
public class TestBean implements Serializable {
private static final long serialVersionUID = -2329929006490721388L;
private List<TestObject> testObjects;
private int selectedId;
public TestBean(){
List<TestObject> to = new ArrayList<TestObject>();
for(int i=0; i<10; i++){
TestObject o = new TestObject(i, "object-"+i);
to.add(o);
}
this.setTestObjects(to);
}
public void testAjaxListener(int id){
System.out.println("testAjaxListener("+id+")");
this.setSelectedId(id);
}
//+getters/setters
}
public class TestObject {
private int id;
private String name;
public TestObject(int id, String name){
this.setId(id);
this.setName(name);
}
//+getters/setters
}
<?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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head></h:head>
<h:body>
<h:form id="testForm">
<h:panelGroup rendered="#{param['view'] eq 'test'}">
<h2>DataTable</h2>
<h:dataTable var="o" value="#{testBean.testObjects}">
<h:column>
<h:commandLink value="#{o.name}" actionListener="#{testBean.testAjaxListener(o.id)}">
<f:ajax
render=":testForm:outputTest"
/>
</h:commandLink>
</h:column>
</h:dataTable>
<h2>output</h2>
<h:outputText id="outputTest" value="#{testBean.selectedId}" />
</h:panelGroup>
</h:form>
</h:body>
</html>
问题是,actionListener不会解雇(我正如你所看到的那样用System.out.print检查)。当我从panelGroup中删除条件渲染时它工作正常,所以我认为这是问题 - 但我该如何解决它? 我已经介绍了这些主题: h:commandLink / h:commandButton is not being invoked, f:ajax inside conditionally rendered custom tag - backing bean method not invoked 还有更多,但它没有解决我的问题:(
请帮忙
答案 0 :(得分:0)
这是因为#{param['view'] eq 'test'}
在JSF忙于处理ajax提交时没有评估true
。然后,它还会再次咨询rendered
,disabled
和readonly
属性,以防止被黑客入侵的请求。 JSF即不包括由<form action>
生成的<h:form>
URL中的请求参数。这匹配commandButton/commandLink/ajax action/listener method not invoked or input value not updated的第5点。
有几种方法可以解决这个问题。
通过<f:viewParam>
将其设置为视图范围bean的属性。
<f:metadata>
<f:viewParam name="view" value="#{testBean.view}" />
</f:metadata>
...
<h:panelGroup rendered="#{testBean.view eq 'test'}">
通过<f:param>
手动保留参数(您需要将其放在每个提交操作中!):
<h:commandLink ...>
<f:param name="view" value="#{param.view}" />
...
</h:commandLink>
将<h:form>
替换为OmniFaces <o:form>
,它能告诉JSF必须将表单提交到包含请求参数的网址:
<o:form includeRequestParams="true">
...
</o:form>