javascript JSF/PrimeFaces ajax 更新破坏了 jQuery 事件侦听器函数绑定
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14400624/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JSF/PrimeFaces ajax updates breaks jQuery event listener function bindings
提问by Uluk Biy
I am registering a change
event listener for every input
in the HTML using jQuery as below:
我正在使用 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>
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.
change
如果用户更改 的内容,则会触发这两个事件myTextarea
。然而,在按下更新按钮后,它会部分更新myTextarea
,之后只有 changeHandler 被触发。绑定的事件$(document).ready()
不再触发。
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.
这是 PrimeFaces 相关和/或预期行为吗?如果是,那么如何确保在不重新运行文档就绪脚本的情况下触发第二个事件。
回答by BalusC
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.
至于您的问题的原因,ajax 请求将使用来自 ajax 响应的新 HTML 元素更新 HTML DOM 树。这些新的 HTML 元素——显然——没有附加 jQuery 事件处理函数。但是,$(document).ready()
不会在 ajax 请求上重新执行。您需要手动重新执行它。
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(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);
});
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:
另一种方法是在 ajax 请求完成时自己显式地重新执行该函数。当您真正有兴趣在ready
/load
事件期间立即执行函数时,这将是唯一的方法(例如,直接应用某些插件特定的行为/外观,例如日期选择器)。首先,您需要将$(document).ready()
作业重构为可重用的函数,如下所示:
$(document).ready(function(){
applyChangeHandler();
});
function applyChangeHandler() {
$(":input").on("change", function() {
console.log("From applyChangeHandler: " + this.id);
});
}
(note that I removed and simplified your completely unnecessary $.each()
approach)
(请注意,我删除并简化了您完全不必要的$.each()
方法)
Then, choose one of the following ways to re-execute it on complete of ajax request:
然后,选择以下方式之一在ajax请求完成时重新执行它:
Use the
oncomplete
attribute of the PrimeFaces command button:oncomplete="applyChangeHandler()"
Use
<h:outputScript target="body">
instead of$(document).ready()
,<h:outputScript id="applyChangeHandler" target="body"> applyChangeHandler(); </h:outputScript>
and reference it in
update
attribute:update=":applyChangeHandler"
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>
Use OmniFaces
<o:onloadScript>
instead of$(document).ready()
,<h:outputScript>
and all on em.<o:onloadScript>applyChangeHandler();</o:onloadScript>
使用
oncomplete
PrimeFaces 命令按钮的属性: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>
在 em 上使用OmniFaces
<o:onloadScript>
而不是$(document).ready()
,<h:outputScript>
。<o:onloadScript>applyChangeHandler();</o:onloadScript>