【问题标题】:How to invoke a JSF managed bean on a HTML DOM event using native JavaScript?如何使用原生 JavaScript 在 HTML DOM 事件上调用 JSF 托管 bean?
【发布时间】:2021-09-12 11:16:53
【问题描述】:

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

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

【问题讨论】:

标签: javascript ajax jsf primefaces facelets


【解决方案1】:

几种方法。

  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中调用它,如下所示:

    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" />
    

  2. 如果您使用 PrimeFaces,请使用其&lt;p:remoteCommand&gt;

    <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" />
    

  3. 如果您使用的是 OmniFaces,请使用其&lt;o:commandScript&gt;。用法与 &lt;h:commandScript&gt; 完全相同,但可用于较旧的 JSF 2.x 版本。

    在第一个示例中,只需将 h: 替换为 o:。历史注释:&lt;h:commandScript&gt; 完全基于&lt;o:commandScript&gt;


  4. 使用“隐藏形式”技巧(实际上,“hack”被赋予了丑陋更好的措辞)。

    <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();
    

    注意在&lt;h:commandButton&gt; 的情况下触发onclick() 而不是click() 的重要性。 onclick() 立即调用onclick 函数,而click() 仅触发元素上的“单击”事件,IE 不支持。如果您使用的是&lt;h:commandLink&gt;,则可以安全地改用click()

    您可以通过&lt;h:inputHidden&gt; 以与您预先由JS 填写的相同的形式传递参数。这在 How to pass JavaScript variables as parameters to JSF action method?

    中得到了证明

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

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

  5. 或者,创建一个自定义 UIComponent,它扩展 UICommand 并生成必要的 JSF 本机 jsf.ajax.request() 调用。例如,您可以查看 OmniFaces &lt;o:commandScript&gt;source code

【讨论】:

  • 感谢 BalusC!问题已通过您的第二个选项解决,使用组件 remoteCommand,现在它可以 100% 工作!
猜你喜欢
  • 2013-01-24
相关资源
最近更新 更多