1

我有一个名为 Index.xhtml 的基本 JSF 页面和一个名为 TestBean.java 的支持 bean。基本上,在 JSF 的 ajax 调用呈现表格后,我试图将子元素附加到表格中的 td 元素。

代码如下。

索引.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:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets">
    <h:head>
        <h:outputScript library="javascript" name="surveyquestions.js"/>
    </h:head>
    <h:body>
        <h:outputLink value="reset.xhtml">reset</h:outputLink>

        <h:form id="myForm">
            <h:panelGroup id="myTable">
                <table>
                    <tr>
                        <td id="targetParent">
                            targetParent here.
                        </td>
                        <td>
                            <h:commandButton value="Click to append a child">
                                <f:ajax event="click" execute="@form"  render="myTable" listener="#{testBean.m()}" onevent="myAppendChild"  />
                            </h:commandButton>
                        </td>
                    </tr>
                </table>

            </h:panelGroup>
        </h:form>

    </h:body>
</html>

支持 bean 只有一个名为 m 的方法,它什么也不做。我有两个 javascript 函数,它们被调用<f:ajax event="click" execute="@form" render="myTable" listener="#{testBean.m()}" onevent="myAppendChild" />

function myAppendChild(data){
    if(data.status == "success"){
        var targetParent = document.getElementById("targetParent")
        alert(targetParent.nodeName);
        alert(targetParent.firstChild.nodeValue);
        var spanTag = document.createElement("span");
        spanTag.innerHTML="child";
        targetParent.appendChild(spanTag);

    }
}

function yourAppendChild(data){
    var addButton = data.source;
    if(data.status == "success"){
        var targetParent = addButton.parentNode.parentNode.cells[0];
        alert(targetParent.nodeName);
        alert(targetParent.firstChild.nodeValue);
        var spanTag = document.createElement("span");
        spanTag.innerHTML="child";
        targetParent.appendChild(spanTag);
    }
}

当我尝试将一个子元素附加到 Id 为targetParent的 td 元素时,我发现第一个 javascript 函数myAppendChild工作正常。但是,第二个功能yourAppendChild仅在我删除render="myTable".

如果我保留render="myTable"yourAppendChild运行到最后,调用 appendChild 没有错误,但不知何故没有附加孩子。

在我看来,这两个函数都获得了完全相同的元素并试图将一个子元素附加到该元素,但第二个函数不适用于render="myTable".

4

1 回答 1

1

当 JSF/ajax 呈现视图时,HTML DOM 树会部分更新/替换为新元素。JS 函数中的addButton元素在yourAppendChild()渲染之前仍然是旧 HTML DOM 树的一部分,但在 JS 函数运行时不再是新 HTML DOM 树的成员。您基本上是在遍历一个悬空引用,它不再指向当前 HTML DOM 树中的任何内容。您基本上需要直接从而不是从中获取addButton元素。documentdata.source

但我建议忘记 JS 方法并采用理智和纯粹的 JSF 方法。您可能会发现这个启动示例很有帮助:推荐的 JSF 2.0 CRUD 框架

于 2012-07-23T22:07:37.367 回答