ajax监听器内部有条件地渲染元素不起作用

时间:2014-09-06 13:16:27

标签: ajax jsf

以下是我的问题的测试用例:

testBean就:

@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
}

的TestObject

public class TestObject {
    private int id;
    private String name;

    public TestObject(int id, String name){
        this.setId(id);
        this.setName(name);
    }

    //+getters/setters
}

Test.xhtml:

<?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 invokedf:ajax inside conditionally rendered custom tag - backing bean method not invoked 还有更多,但它没有解决我的问题:(

请帮忙

1 个答案:

答案 0 :(得分:0)

这是因为#{param['view'] eq 'test'}在JSF忙于处理ajax提交时没有评估true。然后,它还会再次咨询rendereddisabledreadonly属性,以防止被黑客入侵的请求。 JSF即不包括由<form action>生成的<h:form> URL中的请求参数。这匹配commandButton/commandLink/ajax action/listener method not invoked or input value not updated的第5点。

有几种方法可以解决这个问题。

  1. 通过<f:viewParam>将其设置为视图范围bean的属性。

    <f:metadata>
        <f:viewParam name="view" value="#{testBean.view}" />
    </f:metadata>
    ...
    <h:panelGroup rendered="#{testBean.view eq 'test'}">
    
  2. 通过<f:param>手动保留参数(您需要将其放在每个提交操作中!):

    <h:commandLink ...>
        <f:param name="view" value="#{param.view}" />
        ...
    </h:commandLink>
    
  3. <h:form>替换为OmniFaces <o:form>,它能告诉JSF必须将表单提交到包含请求参数的网址:

    <o:form includeRequestParams="true">
        ...
    </o:form>
    
  4. 另见: