简体   繁体   English

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

[英]How to use jsf.ajax.request to manually send ajax request in JSF

I have a table and each row has the 'onclick' configured to call a js function - this part works.我有一个表,每一行都有配置为调用 js 函数的“onclick”——这部分有效。 I would like the function to issue an ajax request to a method that I can somehow define.我希望该函数向我可以以某种方式定义的方法发出 ajax 请求。 Upon return, a div below the table should be rendered.返回时,应呈现表格下方的 div。 Is this possible?这可能吗? I tried the JS function with the code:我用代码尝试了 JS 函数:

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

But it doesn't work of course.但它当然不起作用。 I have no idea what the values of the 'source' parameter (the code above uses 'this') should be, neither do I know what execute in the last parameter should be set to.我不知道“source”参数的值(上面的代码使用“this”)应该是什么,我也不知道最后一个参数中的execute应该设置为什么。 I also don't know how to define the url to be called and the 'action' method.我也不知道如何定义要调用的 url 和 'action' 方法。

The solution could also be using some invisible form somewhere else in the page that get's submitted by the click.解决方案也可以在页面中的其他地方使用一些不可见的表单,通过点击提交。 Can anybody help?有人可以帮忙吗?

As per JSF 2.3, you can use <h:commandScript> for this.根据 JSF 2.3,您可以为此使用<h:commandScript> See also spec issue 613 .另请参阅规范问题 613

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

It's available sinceMojarra 2.3.0-m06 .它从Mojarra 2.3.0-m06 开始可用。


This answer was updated as above 3 years after the question was posted.在问题发布 3 年后,此答案已更新为上述内容。 Below is the original answer when which dates back when <h:commandScript> didn't exist.以下是<h:commandScript>不存在时的原始答案。


I have no idea what the values of the 'source' parameter (the code above uses 'this') should be我不知道“源”参数的值(上面的代码使用“这个”)应该是什么

It should be the client ID of the UICommand component which you'd like to invoke, eg <h:commandLink> , <h:commandButton> , etc as provided by standard JSF API.它应该是您想要调用的UICommand组件的客户端 ID,例如<h:commandLink><h:commandButton>等,由标准 JSF API 提供。 This way JSF will during apply request values phase be able to locate the desired component in the component tree and then queue all of the action(listener)s registered on it.通过这种方式,JSF 将在应用请求值阶段能够在组件树中找到所需的组件,然后将所有注册在其上的操作(侦听器)排队。


neither do I know what execute in the last parameter should be set to.我也不知道最后一个参数中的 execute 应该设置为什么。

It should be the space-separated client IDs of the components which you'd like to process during the form submit.它应该是您希望在表单提交期间处理的组件的以空格分隔的客户端 ID。 It's exactly the same as you'd normally use in <f:ajax execute> .它与您通常在<f:ajax execute>使用的完全相同。


I also don't know how to define the url to be called我也不知道如何定义要调用的 url

Just the current page, as derived from the <form> which is been generated by the <h:form> where the UICommand component is nested in. But you don't need to specify it in jsf.ajax.request() .只是当前页面,从<h:form>生成的<form>派生而来, UICommand组件嵌套在其中。但您不需要在jsf.ajax.request()指定它。 The jsf.js will already determine it based on the client ID of the UICommand component. jsf.js已经根据UICommand组件的客户端 ID 确定它。


and the 'action' method.和“行动”方法。

Just specify the action or actionListener attribute of the target UICommand component the usual way.只需按照通常的方式指定目标UICommand组件的actionactionListener属性UICommand


All with all, your concrete problem is likely that you don't have any UICommand component in the view, so you can't use jsf.ajax.request() .总之,您的具体问题可能是视图中没有任何UICommand组件,因此您不能使用jsf.ajax.request() One way would be to have a form with a command component which is hidden by CSS display:none :一种方法是拥有一个带有命令组件的表单,该组件由 CSS display:none隐藏:

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

Then you can use foo:bar as source parameter.然后你可以使用foo:bar作为source参数。

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

The above does effectively the same as <f:ajax execute="@form" render="div-to-render"> in the command component.上面的内容与命令组件中的<f:ajax execute="@form" render="div-to-render"> You could alternatively also go this path and then use document.getElementById("foo:bar").click() instead of jsf.ajax.request() .您也可以选择此路径,然后使用document.getElementById("foo:bar").click()而不是jsf.ajax.request()

Alternatively, you can also create a custom UICommand component which makes it all a bit easier for JavaScript users.或者,您也可以创建一个自定义UICommand组件,这让 JavaScript 用户更容易一些。 The JSF utility library OmniFaces has such a component, the <o:commandScript> . JSF 实用程序库OmniFaces有一个这样的组件, <o:commandScript> See also its showcase page and source code .另请参阅其展示页面源代码 The JSF component library PrimeFaces has also a similar component in flavor of <p:remoteCommand> . JSF 组件库PrimeFaces也有一个类似<p:remoteCommand>风格的组件。 See also its showcase page .另请参阅其展示页面 RichFaces has a <a4j:jsFunction> which does the same. RichFaces有一个<a4j:jsFunction>做同样的<a4j:jsFunction> See also its showcase page .另请参阅其展示页面

Using native JSF alone, I have no idea how to do that.单独使用本机 JSF,我不知道如何做到这一点。 However, you should take a look at PrimeFace's RemoteCommand .但是,您应该看看 PrimeFace 的RemoteCommand It's exactly what you need at the moment.这正是您目前所需要的。 It would be something like this:它会是这样的:

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

<h:someComponent onclick="onRowClick" />

Ok, so I managed to implement what I need, with all the ways suggested by BalusC, with <a4j:jsFunction> looking the best by a wide margin.好的,所以我设法实现了我需要的东西,使用 BalusC 建议的所有方法,<a4j:jsFunction> 看起来是最好的。 The reason I am writing a follow up is that there were more things wrong which I initially didn't include in the question and there is not enough comment space ;d我写后续的原因是有更多的错误我最初没有包含在问题中并且没有足够的评论空间;d

  1. My form was in the wrong place - it was placed within the 'table':我的表格在错误的地方 - 它被放置在“表格”中:

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

    Whereas it works for non-Ajax, id doesn't work for Ajax requests.虽然它适用于非 Ajax,但 id 不适用于 Ajax 请求。 Moving it right below the table caused the requests to be submitted.将它移动到表格正下方导致请求被提交。

  2. The panel that I wanted to render was rendered='false' initially, which caused the HTML markup not to be output in the first place.我想要渲染的面板最初是 render='false' ,这导致 HTML 标记首先不输出。 When the Ajax call returned, it couldn't find an element with the id I wanted to render, and resulted in error dialogs or nothing at all (depending on the method).当 Ajax 调用返回时,它找不到具有我想要呈现的 id 的元素,并导致错误对话框或根本没有(取决于方法)。 The solution was to use a wrapper div with the id in question that was always rendered, and use conditional rendering only within that div.解决方案是使用带有始终呈现的相关 id 的包装 div,并仅在该 div 内使用条件呈现。 So, instead of:所以,而不是:

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

    I needed to do this:我需要这样做:

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

Thanks for all the help.感谢所有的帮助。 I will leave the post by BalusC as the correct one as it was really correct, with my own errors influencing the whole thing.我将 BalusC 的帖子保留为正确的帖子,因为它确实是正确的,我自己的错误会影响整件事。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM