如何使用本地JavaScript在HTML DOM事件中调用JSF托管的bean?

17

我需要在HTML DOM的load事件期间使用ajax执行JSF管理的bean动作方法,类似于jQuery的$(document).ready(function() { $.ajax(...) })。在此项目中,我只能使用由JSF生成的JavaScript。有没有一种在本机JSF中执行此操作的方法?我可以使用哪个事件或哪个JSF ajax函数?

我正在使用JSF 2.0、Facelets和PrimeFaces。


1
想必这个问题会对你有所帮助:https://dev59.com/vXA65IYBdhLWcg3wqQc8。 - Heppy Karlsson
3
不,它绝对不是。你是否刚接触JSF? - BalusC
1个回答

35

几种方法。

  1. 使用<h:commandScript>。请注意,此功能仅适用于 JSF 2.3 以后的版本。

 <h:form>
     <h:commandScript name="commandName" action="#{bean.action}" render=":results" />
 </h:form>
 <h:panelGroup id="results">
     ...
 </h:panelGroup>
您可以在JS中按以下方式调用它:

您可以按照以下方式在JS中调用它:

 commandName();

参数可以按以下方式传递:

 commandName({ name1: "value1", name2: "value2" });

并按以下方式获得:

 String name1 = externalContext.getRequestParameterMap().get("name1"); // value1
 String name2 = externalContext.getRequestParameterMap().get("name2"); // value2

要在 load 事件期间调用它,请设置 autorun="true"

 <h:commandScript ... autorun="true" />

  • 如果您正在使用PrimeFaces,请使用其<p:remoteCommand>

     <h:form>
         <p:remoteCommand name="commandName" action="#{bean.action}" update=":results" />
     </h:form>
     <h:panelGroup id="results">
         ...
     </h:panelGroup>
    
    您可以在JS中如下调用它:
     commandName();
    

    然而,这并不使用JSF本机的jsf.ajax.request(),而是使用PrimeFaces本地的jQuery(您知道,PrimeFaces是基于jQuery/UI的JSF组件库)。

    参数可以如下传递:

     commandName([{ name: "name1", value: "value1" }, { name: "name2", value: "value2" }]);
    

    并按以下方式获取:

     String name1 = externalContext.getRequestParameterMap().get("name1"); // value1
     String name2 = externalContext.getRequestParameterMap().get("name2"); // value2
    

    要在 load 事件期间调用它,请设置 autoRun="true"

     <p:remoteCommand ... autoRun="true" />
    

  • 如果您正在使用OmniFaces,请使用其<o:commandScript>。 用法与<h:commandScript>完全相同,但适用于旧版本的JSF 2.x。

    只需在第一个示例中将h:替换为o:。历史注释: <h:commandScript>完全基于<o:commandScript>


  • 使用“隐藏表单”技巧(实际上,“黑客”是更好的措辞,鉴于其丑陋性)。

     <h:form id="form" style="display:none;">
         <h:commandButton id="button" action="#{bean.action}">
             <f:ajax render=":results" />
         </h:commandButton>
     </h:form>
     <h:panelGroup id="results">
         ...
     </h:panelGroup>
    

    您可以按以下方式在JS中调用它:

     document.getElementById("form:button").onclick();
    

    注意要触发onclick()而不是click()的重要性。 onclick()会立即调用生成的onclick函数,而click()基本上只模拟元素上的“点击”操作,就像使用鼠标一样,在IE中不受支持,并且在某些浏览器中还需要实际可交互的元素(即display:none不能被使用)。

    您可以通过<h:inputHidden>在JS之前填充相同的表单中传递参数。在如何将JavaScript变量作为参数传递给JSF操作方法?中演示了这一点。

    要在load事件期间调用它,请考虑将其放入<h:outputScript target="body">中。 target="body"会自动将<script>放在<body>的末尾,因此不需要一个$(document).ready()包装器。

     <h:outputScript target="body">
         document.getElementById("form:button").onclick();
     </h:outputScript>
    

  • 或者,创建一个自定义的UIComponent扩展UICommand并生成必要的JSF本地jsf.ajax.request()调用。例如,您可以查看OmniFaces的<o:commandScript>源代码


  • 谢谢BalusC!使用您的第二个选项,使用组件remoteCommand解决了问题,现在它已经100%工作! - Tiago Vieira Dos Santos

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接