【问题标题】:How to use jsf.ajax.request to manually send ajax request in JSFJSF中如何使用jsf.ajax.request手动发送ajax请求
【发布时间】:2013-03-11 02:50:49
【问题描述】:

我有一个表,每一行都配置了“onclick”以调用 js 函数——这部分有效。我希望该函数向我可以以某种方式定义的方法发出 ajax 请求。返回后,应呈现表格下方的 div。这可能吗?我用代码尝试了JS函数:

<h:outputScript library="javax.faces" name="jsf.js" />
...
function clickAndRender() {
  jsf.ajax.request(this, event, {render: 'div-to-render'})
}

但它当然不起作用。我不知道'source'参数的值(上面的代码使用'this')应该是什么,我也不知道最后一个参数中的执行应该设置为什么。我也不知道如何定义要调用的url和'action'方法。

解决方案也可以在页面的其他地方使用一些不可见的表单,这些表单是通过点击提交的。有人可以帮忙吗?

【问题讨论】:

    标签: javascript ajax jsf-2


    【解决方案1】:

    根据 JSF 2.3,您可以为此使用 &lt;h:commandScript&gt;。另见spec issue 613

    <h:form>
        <h:commandScript name="foo" action="#{bean.action}" render="div-to-render" />
    </h:form>
    
    function clickAndRender() {
        foo();
    }
    

    它从Mojarra 2.3.0-m06开始可用。


    此答案在问题发布 3 年后更新为上述内容。以下是 &lt;h:commandScript&gt; 不存在时的原始答案。


    我不知道'source'参数的值(上面的代码使用'this')应该是什么

    它应该是您要调用的 UICommand 组件的客户端 ID,例如&lt;h:commandLink&gt;&lt;h:commandButton&gt; 等由标准 JSF API 提供。这样,JSF 将在应用请求值阶段能够在组件树中找到所需的组件,然后将所有注册在其上的操作(侦听器)排队。


    我也不知道最后一个参数中的执行应该设置成什么。

    它应该是您希望在表单提交期间处理的组件的以空格分隔的客户端 ID。它与您通常在&lt;f:ajax execute&gt; 中使用的完全相同。


    我也不知道怎么定义要调用的url

    只是当前页面,从&lt;h:form&gt; 生成的&lt;form&gt; 派生,UICommand 组件嵌套在其中。但您不需要在jsf.ajax.request() 中指定它。 jsf.js 已经根据 UICommand 组件的客户端 ID 确定它。


    还有“action”方法。

    只需按常规方式指定目标UICommand 组件的actionactionListener 属性即可。


    总而言之,您的具体问题可能是您的视图中没有任何UICommand 组件,因此您不能使用jsf.ajax.request()。一种方法是创建一个带有命令组件的表单,该组件被 CSS display:none 隐藏:

    <h:form id="foo" style="display:none">
        <h:commandLink id="bar" action="#{bean.method}" />
    </h:form>
    

    那么你可以使用foo:bar作为source参数。

    jsf.ajax.request('foo:bar', null, {'javax.faces.behavior.event': 'action', 'execute': '@form', 'render': 'div-to-render'});
    

    上面的内容实际上与命令组件中的&lt;f:ajax execute="@form" render="div-to-render"&gt; 相同。您也可以选择这条路径,然后使用document.getElementById("foo:bar").click() 而不是jsf.ajax.request()

    另外,您还可以创建一个自定义的UICommand 组件,这对 JavaScript 用户来说更容易一些。 JSF 实用程序库OmniFaces 有这样一个组件,&lt;o:commandScript&gt;。另见其showcase pagesource code。 JSF 组件库PrimeFaces 也有一个类似的组件&lt;p:remoteCommand&gt;。另请参阅其showcase pageRichFaces 有一个 &lt;a4j:jsFunction&gt;,它的作用相同。另见其showcase page

    【讨论】:

    • 不幸的是,它不起作用。在 chrome 中,我收到以下消息:未捕获的 clientError: Sourceform 无法确定,要么是因为元素未附加到表单,要么我们有多个具有相同标识符或名称的命名元素的表单,停止 ajax 处理 jsf.js: 8352 _MF_SINGLTN._getForm jsf.js:8352 _MF_SINGLTN.request jsf.js:8264 request jsf.js:8947 signatureClicked onclick 我尝试了显式调用 jsf.ajax.request 的方法。
    • 它确实适用于 $("#foo\\:bar").click() (我使用的是 jquery)。如果您有时间,我很想了解第一种方法有什么问题。并感谢您的帮助!
    • 不客气。至于您最初的问题,您似乎正在使用 RichFaces 命令组件(该错误消息特定于 RichFaces)。抱歉,如果没有看到 SSCCE,我无法回答那部分。我只能告诉你应该只使用&lt;a4j:jsFunction&gt; 没有那个丑陋的 jsf.ajax.request 或 jQuery 解决方法:)
    • 我设法创建了一个不起作用的 SSCCE ;d。最初的错误是由在 中嵌套 引起的,这对于非 ajax 请求工作正常。现在我得到一个更奇怪的错误 - 我看到调用了服务器代码,我看到它是 Ajax,我看到正在设置的值,但随后我在浏览器中看到一个对话框:错误消息:无法设置属性“名称”未定义的错误名称:clientError 服务器错误名称:TypeError 注意,此消息仅发送,因为项目阶段是开发阶段,没有注册其他错误侦听器。您希望我如何将项目提供给您?
    • 我也没有用 做到这一点。函数生成好了,调用了服务器,但是面板没有重新渲染。
    【解决方案2】:

    单独使用原生 JSF,我不知道该怎么做。不过,您应该看看 PrimeFace 的RemoteCommand。这正是您目前所需要的。应该是这样的:

    <p:remoteCommand name="onRowClick" actionListener="myBean.onRowClick" update="div-to-render" />
    
    <h:someComponent onclick="onRowClick" />
    

    【讨论】:

      【解决方案3】:

      好的,所以我设法用 BalusC 建议的所有方法实现了我需要的东西,而 看起来是最好的。我写后续文章的原因是我最初没有在问题中包含更多错误的内容,并且没有足够的评论空间;d

      1. 我的表格放错地方了——它被放在了“表格”中:

        <table>
          <ui:repeat>...</ui:repeat>
          <form>...</form>
        </table>
        

        虽然它适用于非 Ajax,但 id 不适用于 Ajax 请求。将其移动到表格正下方会导致提交请求。

      2. 我要渲染的面板最初是 render='false' ,这导致 HTML 标记一开始就没有输出。当 Ajax 调用返回时,它找不到具有我想要呈现的 id 的元素,并导致错误对话框或什么都没有(取决于方法)。解决方案是使用始终呈现相关 id 的包装 div,并仅在该 div 内使用条件呈现。所以,而不是:

        <h:outputText id="to-render" rendered="${bean.clicked != null}">
          ...
        </h:outputText>
        

        我需要这样做:

        <h:panelGroup layout="block" id="to-render">
          <h:outputText rendered="${bean.clicked != null}">
            ...
          </h:outputText>
        </h:panelGroup>
        

      感谢所有帮助。我会把 BalusC 的帖子保留为正确的,因为它确实是正确的,我自己的错误会影响整个事情。

      【讨论】:

        猜你喜欢
        • 2023-03-14
        • 2011-09-05
        • 2010-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-14
        • 1970-01-01
        相关资源
        最近更新 更多