在每次 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 组件,您需要使用 &lt;p:ajax&gt; 而不是 &lt;f:ajax&gt;。但是为什么不直接使用 CSS 来覆盖默认样式呢?无论如何,在您未来的 JSF 问题中,请指定您正在使用的组件库以及功能要求。 我想我可以,但是有几个类应用于每个输入并包含跨度,每个类都有多种不同的样式。我与它斗争了三个多小时,直到我意识到几行 jQuery 完美地删除了所有有问题的样式。 Primefaces 团队似乎在 3.0 中添加了关闭表单主题的功能,但它仍然是一个相对不稳定的版本,有很多错误。我宁愿避免这种情况,因为除了最后剩下的问题外,我只是按照我需要的方式得到了一切。编辑:啊……让我试试 p:ajax,我会回来的。 好吧,这也不起作用,因为 p:ajax 只能应用于允许您指定向导或选项卡不指定的客户端行为的组件。我再次尝试用我自己的类覆盖样式,但发现无论我做什么,primefaces 主题样式表总是会覆盖我的样式表。如果我首先在页面中声明我的样式表,那么事情就会大打折扣,我不知道为什么。我在这里几乎没有想法。

以上是关于在每次 JSF ajax 回发后执行 JavaScript的主要内容,如果未能解决你的问题,请参考以下文章

回发后jquery datepicker不起作用

回发后执行 Javascript,并在 C# 中清除响应

从更新面板异步回发后保持滚动位置

回发后asp.net jquery脚本未运行

回发后未调用模态对话框的 onshow

GridView 上的 jQuery 函数在页面回发后停止工作(鼠标悬停,单击)