JSF/PrimeFaces ajax 更新破坏了 jQuery 事件侦听器函数绑定 [英] JSF/PrimeFaces ajax updates breaks jQuery event listener function bindings

查看:32
本文介绍了JSF/PrimeFaces ajax 更新破坏了 jQuery 事件侦听器函数绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am registering a change event listener for every input in the HTML using jQuery as below:

<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 的内容,两个 change 事件都会被触发.然而,在按下更新按钮后,部分更新了 myTextarea,之后只有 changeHandler 被触发.$(document).ready() 中绑定的事件不再触发.

Both change events are being triggered if the user changes the content of myTextarea. However after pressing the update button, which partially updates the myTextarea, only the changeHandler is triggering afterwards. The event bound in $(document).ready() is not triggering anymore.

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

Is this PrimeFaces related and/or an expected behavior? If yes then how can I ensure to trigger the second event without rerunning document ready script again.

推荐答案

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

As to the cause of your problem, the ajax request will update the HTML DOM tree with new HTML elements from the ajax response. Those new HTML elements do —obviously— not have the jQuery event handler function attached. However, the $(document).ready() isn't re-executed on ajax requests. You need to manually re-execute it.

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

This can be achieved in various ways. The simplest way is to use $(document).on(event, selector, function) instead of $(selector).on(event, function). This is tied to the document and the given functionRef is always invoked when the given eventName is triggered on an element matching the given selector. So you never need to explicitly re-execute the function by JSF means.

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

<小时>

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


The alternative way is to explicitly re-execute the function yourself on complete of ajax request. This would be the only way when you're actually interested in immediately execute the function during the ready/load event (e.g. to directly apply some plugin specific behavior/look'n'feel, such as date pickers). First, you need to refactor the $(document).ready() job into a reusable function as follows:

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

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

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

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

Then, choose one of the following ways to re-execute it on complete of ajax request:

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

oncomplete="applyChangeHandler()"

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

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

    并在 update 属性中引用它:

    and reference it in update attribute:

    update=":applyChangeHandler"
    

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

  • Use <p:outputPanel autoUpdate="true"> to auto update it on every ajax request:

    <p:outputPanel autoUpdate="true">
        <h:outputScript id="applyChangeHandler">
            applyChangeHandler();
        </h:outputScript>
    </p:outputPanel>
    

  • 使用 OmniFaces 而不是 $(document).ready(), 等等.

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

  • 这篇关于JSF/PrimeFaces ajax 更新破坏了 jQuery 事件侦听器函数绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆