繁体   English   中英

JSF/PrimeFaces ajax 更新破坏了 jQuery 事件侦听器函数绑定

[英]JSF/PrimeFaces ajax updates breaks jQuery event listener function bindings

我正在使用 jQuery 为 HTML 中的每个input注册一个change事件侦听器,如下所示:

<h:head>
    <script type="text/javascript">
        //<![CDATA[
        $(document).ready(function(){
            $(':input').each(function() {
                $(this).change(function() {
                    console.log('From docReady: ' + this.id);
                });
            });
        });

        function changeHandler() {
            console.log("from changeHandler");
        }
        //]]>
    </script>
</h:head>
<h:body>
    <h:form id="topForm">
        <p:commandButton id="myButton" value="update"
                         action="#{testBean.submit}"
                         partialSubmit="true" process=":myForm:panel"
                         update=":myForm:panel" />
    </h:form>
    <h:form id="myForm">
        <p:panel id="panel">
            <p:inputTextarea id="myTextarea"
                             value="#{testBean.val}"
                             onchange="changeHandler();"/>
        </p:panel>
    </h:form>
</h:body>

如果用户更改myTextarea的内容, myTextarea触发这两个change事件。 然而,按下更新按钮后,部分更新myTextarea ,之后仅触发 changeHandler 。 $(document).ready()绑定的事件不再触发。

这是 PrimeFaces 相关和/或预期行为吗? 如果是,那么如何确保在不重新运行文档就绪脚本的情况下触发第二个事件。

至于您的问题的原因,ajax 请求将使用来自 ajax 响应的新 HTML 元素更新 HTML DOM 树。 这些新的 HTML 元素——显然——没有附加 jQuery 事件处理函数。 但是, $(document).ready()不会在 ajax 请求上重新执行。 您需要手动重新执行它。

这可以通过多种方式实现。 最简单的方法是使用$(document).on(event, selector, function)而不是$(selector).on(event, function) 这与文档相关联,并且当给定的eventName在匹配给定selector的元素上触发时,总是调用给定的functionRef 因此,您永远不需要通过 JSF 方式显式地重新执行该函数。

$(document).on("change", ":input", function() {
    console.log("From change event on any input: " + this.id);
});

另一种方法是在 ajax 请求完成时自己显式地重新执行该函数。 当您真正有兴趣在ready / load事件期间立即执行函数时,这将是唯一的方法(例如,直接应用某些插件特定的行为/外观,例如日期选择器)。 首先,您需要将$(document).ready()作业重构为一个可重用的函数,如下所示:

$(document).ready(function(){
    applyChangeHandler();
});

function applyChangeHandler() {
    $(":input").on("change", function() {
        console.log("From applyChangeHandler: " + this.id);
    });
}

(请注意,我删除并简化了您完全不必要的$.each()方法)

然后,选择以下方式之一在ajax请求完成时重新执行它:

  1. 使用 PrimeFaces 命令按钮的oncomplete属性:

     oncomplete="applyChangeHandler()"
  2. 使用<h:outputScript target="body">而不是$(document).ready()

     <h:outputScript id="applyChangeHandler" target="body"> applyChangeHandler(); </h:outputScript>

    并在update属性中引用它:

     update=":applyChangeHandler"
  3. 使用<p:outputPanel autoUpdate="true">在每个 ajax 请求上自动更新它:

     <p:outputPanel autoUpdate="true"> <h:outputScript id="applyChangeHandler"> applyChangeHandler(); </h:outputScript> </p:outputPanel>
  4. 使用OmniFaces <o:onloadScript>而不是$(document).ready() , <h:outputScript>和所有在 em 上的。

     <o:onloadScript>applyChangeHandler();</o:onloadScript>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM