为了账号安全,请及时绑定邮箱和手机立即绑定

JSF / PrimeFaces Ajax更新中断了jQuery事件侦听器功能绑定

JSF / PrimeFaces Ajax更新中断了jQuery事件侦听器功能绑定

梦里花落0921 2019-11-20 10:57:00
我正在使用jQuery为HTML中的change每个事件注册一个事件侦听器,input如下所示:<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>change如果用户更改的内容,则会触发这两个事件myTextarea。但是,在按下update按钮(部分更新)之后myTextarea,只有changeHandler之后才触发。绑定的事件$(document).ready()不再触发。这是PrimeFaces相关和/或预期的行为吗?如果是,那么我如何确保触发第二个事件而无需再次运行文档就绪脚本。
查看完整描述

2 回答

?
杨__羊羊

TA贡献1943条经验 获得超7个赞

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


这可以通过多种方式来实现。最简单的方法是使用$(document).on(event, selector, function)而不是$(selector).on(event, function)。这与文档相关联,并且在匹配给定的元素上触发给定时functionRef,总是会调用给eventName定selector。因此,您无需通过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请求完成时重新执行它:


使用oncompletePrimeFaces命令按钮的属性:


oncomplete="applyChangeHandler()"

使用<h:outputScript target="body">代替$(document).ready(),


<h:outputScript id="applyChangeHandler" target="body">

    applyChangeHandler();

</h:outputScript>

并在update属性中引用它:


update=":applyChangeHandler"

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


<p:outputPanel autoUpdate="true">

    <h:outputScript id="applyChangeHandler">

        applyChangeHandler();

    </h:outputScript>

</p:outputPanel>

使用OmniFaces <o:onloadScript>代替$(document).ready(),<h:outputScript>并在em上全部使用。


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


查看完整回答
反对 回复 2019-11-20
?
郎朗坤

TA贡献1921条经验 获得超9个赞

感谢您的发布。看来第三选择适合我的用例。我打算将该代码块放入facelet模板中。对于第三种方式,我删除了$(document).ready(function(){},否则在初始页面加载时该处理程序被注册了两次,然后将autoUpdatable p:outputPanel手动置于正文的末尾。我自己实现Omnifaces已经提供的功能,肯定会尝试一下。:) 

查看完整回答
反对 回复 2019-11-20
  • 2 回答
  • 0 关注
  • 527 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信