如何使用本机 JavaScript 在 HTML DOM 事件上调用 JSF 托管 bean?

IT技术 javascript ajax jsf primefaces facelets
2021-01-23 13:12:03

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

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

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,请使用其<p:remoteCommand>.

    <h:form>
        <p:remoteCommand name="commandName" action="#{bean.action}" update=":results" />
    </h:form>
    <h:panelGroup id="results">
        ...
    </h:panelGroup>
    

    您可以在 JS 中调用它,如下所示:

    commandName();
    

    然而,这不使用 JSF native 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,请使用其<o:commandScript>. 用法与 with 完全相同,<h:commandScript>但可用于较旧的 JSF 2.x 版本。

    只需在第一个示例中替换h:o:历史记录:<h:commandScript>完全基于<o:commandScript>.


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

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

    您可以通过<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>
    

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

感谢 BalusC!问题已通过您的第二个选项解决,使用组件 remoteCommand,现在它 100% 工作!
2021-03-15 13:12:03