在每次 JSF ajax 回发后执行 JavaScript
Posted
技术标签:
【中文标题】在每次 JSF ajax 回发后执行 JavaScript【英文标题】:Execute JavaScript after every JSF ajax postback 【发布时间】:2011-08-08 19:50:21 【问题描述】:我有一个 javascript 函数,我想在 JSF 2 中的每次异步回发后执行它。
我已执行以下操作以确保执行每个完整页面回发:
jQuery(document).ready(mahFunction);
我需要这样做的原因是为了解决第三方 JSF 组件库中的故障,因此我无法在服务器渲染阶段修改任何内容来为组件执行此操作。
我无法找到这方面的信息,这可能是因为我使用了不正确的术语。我曾经是一名 ASP.NET 开发人员,我将这些术语称为“整页回发”和“部分回发”,而其他 JSF 开发人员似乎不使用这些术语。
【问题讨论】:
【参考方案1】:您可以通过jsf.ajax.addOnEvent
将其注册为 JSF ajax 回调处理程序:
<script>
jsf.ajax.addOnEvent(foo);
</script>
与
<script>
function foo(data)
var ajaxStatus = data.status; // Can be "begin", "complete" and "success".
switch (ajaxStatus)
case "begin": // Right before sending ajax request.
// ...
break;
case "complete": // Right after receiving ajax response.
// ...
break;
case "success": // When ajax response is successfully processed.
// ...
break;
</script>
data
对象有几个有用的 XHR 派生属性,这些属性在JSF 2.0 specification 的表 14-4 中进行了描述(单击进行评估链接)。以下是相关性摘录:
表 14-4 事件数据负载
名称 描述/值 ------------- ------------------------------------- --------------- 输入“事件” status 表 14-3 中指定的事件之一 source 触发 Ajax 请求的 DOM 元素。 responseCode Ajax 请求对象“状态”(XMLHttpRequest.status); “开始”事件不存在; responseXML XML 响应 (XMLHttpRequest.responseXML); “开始”事件不存在; responseText 文本响应(XMLHttpResponse.responseTxt); “开始”事件不存在;
作为一种替代方法,Xhtml 声明式方法是将脚本调用嵌入到带有id
的 JSF 组件中,然后让 ajax 调用重新渲染它。组件应依次根据FacesContext#isPostback()
有条件地呈现脚本。
<h:form>
<h:commandButton value="Submit" action="#bean.submit">
<f:ajax render=":myscript">
</h:commandButton>
</h:form>
<h:panelGroup id="myscript">
<h:outputScript rendered="#facesContext.postback">foo();</h:outputScript>
</h:panelGroup>
然而,大多数组件库对此都有更好的抽象支持。由于您没有提及您使用的是哪一个以便给出更合适的答案,这里只是一个基于PrimeFaces 命令按钮的随机示例。
<p:commandButton value="Submit" action="#bean.submit" oncomplete="foo();" />
请参阅您正在使用的组件库的文档。
另见:
How to re-execute javascript function after form reRender?【讨论】:
我确实在使用 Primefaces 组件库,但是我需要的特定组件没有 oncomplete 属性。我尝试了您的两个建议,但它们都没有导致我的 javascript 在回发后被调用。我在 Firebug 中放置了一个断点来验证这一点。 有问题的组件是 p:calendar 和 p:inputMask。我的 javascript 从这些组件中的输入元素中删除了主题类。这通常工作正常,但它们在 p:wizard 中,并且每次发生部分回发以导航到下一个选项卡时,javascript 都不会被调用。表单上的验证错误会阻止调用此 javascript 吗? PrimeFaces 可能附带了它自己的 JS ajax 库。请注意,对于 PrimeFaces 组件,您需要使用<p:ajax>
而不是 <f:ajax>
。但是为什么不直接使用 CSS 来覆盖默认样式呢?无论如何,在您未来的 JSF 问题中,请指定您正在使用的组件库以及功能要求。
我想我可以,但是有几个类应用于每个输入并包含跨度,每个类都有多种不同的样式。我与它斗争了三个多小时,直到我意识到几行 jQuery 完美地删除了所有有问题的样式。 Primefaces 团队似乎在 3.0 中添加了关闭表单主题的功能,但它仍然是一个相对不稳定的版本,有很多错误。我宁愿避免这种情况,因为除了最后剩下的问题外,我只是按照我需要的方式得到了一切。编辑:啊……让我试试 p:ajax,我会回来的。
好吧,这也不起作用,因为 p:ajax 只能应用于允许您指定向导或选项卡不指定的客户端行为的组件。我再次尝试用我自己的类覆盖样式,但发现无论我做什么,primefaces 主题样式表总是会覆盖我的样式表。如果我首先在页面中声明我的样式表,那么事情就会大打折扣,我不知道为什么。我在这里几乎没有想法。以上是关于在每次 JSF ajax 回发后执行 JavaScript的主要内容,如果未能解决你的问题,请参考以下文章