如何使用jsf.ajax.request在JSF中手动发送ajax请求

时间:2013-03-21 14:23:32

标签: javascript ajax jsf-2

我有一个表,每行都配置了'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'方法。

解决方案也可以在页面中的某个其他地方使用一些不可见的形式,通过点击提交。有人可以帮忙吗?

3 个答案:

答案 0 :(得分:10)

根据JSF 2.3,您可以使用<h:commandScript>。另请参阅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年后更新。以下是<h:commandScript>不存在时的原始答案。


  

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

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


  

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

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


  

我也不知道如何定义要调用的网址

当前页面,源自<form><h:form>由嵌套UICommand组件的jsf.ajax.request()生成。但您无需在其中指定jsf.jsUICommand将根据action组件的客户端ID确定它。


  

和'action'方法。

只需按常规方式指定目标actionListener组件的UICommandUICommand属性。


总而言之,您的具体问题可能是视图中没有任何jsf.ajax.request()组件,因此您无法使用display:none。一种方法是使一个带有命令组件的表单被CSS <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'}); 参数。

<f:ajax execute="@form" render="div-to-render">

上述内容与命令组件中的document.getElementById("foo:bar").click()实际上相同。您也可以选择此路径,然后使用jsf.ajax.request()代替UICommand

或者,您也可以创建自定义{{1}}组件,这使JavaScript用户更容易一些。 JSF实用程序库OmniFaces具有<o:commandScript>这样的组件。另请参见其showcase pagesource code。 JSF组件库PrimeFaces也有类似<p:remoteCommand>风格的组件。另见showcase pageRichFaces<a4j:jsFunction>也是如此。另见showcase page

答案 1 :(得分:0)

单独使用原生JSF,我不知道如何做到这一点。但是,你应该看看PrimeFace的RemoteCommand。这正是您目前所需要的。它会是这样的:

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

<h:someComponent onclick="onRowClick" />

答案 2 :(得分:0)

好的,所以我设法用BalusC建议的所有方法实现我需要的,&lt; a4j:jsFunction&gt;大范围看起来最好。我正在撰写跟进报告的原因是,我最初没有在问题中包含更多错误,并且没有足够的评论空间; d

  1. 我的表单位于错误的位置 - 它放在'table'中:

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

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

  2. 我想渲染的面板最初渲染='false',这导致HTML标记首先不输出。当Ajax调用返回时,它找不到具有我想要呈现的id的元素,并导致错误对话框或根本没有(取决于方法)。解决方案是使用一个包装器div,其中包含始终呈现的id,并且仅在该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>
    
  3. 感谢所有帮助。我将保留BalusC的帖子作为正确的帖子,因为它确实是正确的,我自己的错误影响了整个事情。