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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15550165/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 01:10:05  来源:igfitidea点击:

How to use jsf.ajax.request to manually send ajax request in JSF

javascriptajaxjsf-2

提问by wujek

I have a table and each row has the 'onclick' configured to call a js function - this part works. I would like the function to issue an ajax request to a method that I can somehow define. Upon return, a div below the table should be rendered. Is this possible? I tried the JS function with the code:

我有一个表格,每一行都有配置为调用 js 函数的“onclick”——这部分有效。我希望该函数向我可以以某种方式定义的方法发出 ajax 请求。返回时,应呈现表格下方的 div。这可能吗?我用代码尝试了 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. I also don't know how to define the url to be called and the 'action' method.

但它当然不起作用。我不知道“source”参数的值(上面的代码使用“this”)应该是什么,我也不知道最后一个参数中的execute应该设置为什么。我也不知道如何定义要调用的 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?

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

回答by BalusC

As per JSF 2.3, you can use <h:commandScript>for this. See also spec issue 613.

根据 JSF 2.3,您可以使用<h:commandScript>它。另请参阅规范问题 613

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

function clickAndRender() {
    foo();
}

It's available since Mojarra 2.3.0-m06.

Mojarra 2.3.0-m06起可用。



This answer was updated as above 3 years after the question was posted. Below is the original answer when which dates back when <h:commandScript>didn't exist.

在问题发布 3 年后,此答案已更新为上述内容。以下是原始答案,可追溯到<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 UICommandcomponent which you'd like to invoke, e.g. <h:commandLink>, <h:commandButton>, etc as provided by standard 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.

它应该是在客户端ID UICommand,你想调用组件,例如<h:commandLink><h:commandButton>通过标准API JSF提供等。这样 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. It's exactly the same as you'd normally use in <f:ajax execute>.

它应该是您希望在表单提交期间处理的组件的以空格分隔的客户端 ID。它与您通常在<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 UICommandcomponent is nested in. But you don't need to specify it in jsf.ajax.request(). The jsf.jswill already determine it based on the client ID of the UICommandcomponent.

只是当前页面,派生自由组件嵌套<form><h:form>位置生成的UICommand。但您不需要在 中指定它jsf.ajax.request()。该jsf.js会已确定其基础上的客户端IDUICommand组件。



and the 'action' method.

和“行动”方法。

Just specify the actionor actionListenerattribute of the target UICommandcomponent the usual way.

只需按照通常的方式指定目标组件的actionoractionListener属性即可UICommand



All with all, your concrete problem is likely that you don't have any UICommandcomponent in the view, so you can't use jsf.ajax.request(). One way would be to have a form with a command component which is hidden by CSS display:none:

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

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

Then you can use foo:baras sourceparameter.

然后你可以使用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. You could alternatively also go this path and then use document.getElementById("foo:bar").click()instead of jsf.ajax.request().

上面的内容与<f:ajax execute="@form" render="div-to-render">命令组件中的效果相同。您也可以选择这条路径,然后使用document.getElementById("foo:bar").click()代替jsf.ajax.request().

Alternatively, you can also create a custom UICommandcomponent which makes it all a bit easier for JavaScript users. The JSF utility library OmniFaceshas such a component, the <o:commandScript>. See also its showcase pageand source code. The JSF component library PrimeFaceshas also a similar component in flavor of <p:remoteCommand>. See also its showcase page. RichFaceshas a <a4j:jsFunction>which does the same. See also its showcase page.

或者,您也可以创建一个自定义UICommand组件,这让 JavaScript 用户更容易一些。JSF 实用程序库OmniFaces有这样一个组件,<o:commandScript>. 另请参阅其展示页面源代码。JSF 组件库PrimeFaces也有类似的<p:remoteCommand>. 另请参阅其展示页面RichFaces具有<a4j:jsFunction>相同的功能。另请参阅其展示页面

回答by Mr.J4mes

Using native JSF alone, I have no idea how to do that. However, you should take a look at PrimeFace's RemoteCommand. It's exactly what you need at the moment. It would be something like this:

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

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

<h:someComponent onclick="onRowClick" />

回答by wujek

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. 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

好的,所以我设法实现了我需要的东西,使用 BalusC 建议的所有方法,<a4j:jsFunction> 看起来是最好的。我写后续的原因是有更多的错误我最初没有包含在问题中并且没有足够的评论空间;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. 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. 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). 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. 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>
    
  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>
    

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 的帖子保留为正确的帖子,因为它确实是正确的,我自己的错误影响了整件事。