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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16588327/
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 05:13:37  来源:igfitidea点击:

How to invoke a JSF managed bean on a HTML DOM event using native JavaScript?

javascriptajaxjsfprimefacesfacelets

提问by Tiago Vieira Dos Santos

I need to execute a JSF managed bean action method using ajax during HTML DOM loadevent, similar to jQuery's $(document).ready(function() { $.ajax(...) }). I can only use the JavaScript generated by JSF in this project. Is there a way to do it in native JSF? Which event can I use or which JSF ajax function can I use?

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

I'm using JSF 2.0, Facelets and PrimeFaces.

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

回答by BalusC

Several ways.

几种方式。

  1. Use <h:commandScript>. Note that this is only available since JSF 2.3.

    <h:form>
        <h:commandScript name="commandName" action="#{bean.action}" render=":results" />
    </h:form>
    <h:panelGroup id="results">
        ...
    </h:panelGroup>
    

    You can invoke it in JS as below:

    commandName();
    

    The parameters can be passed as below:

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

    And obtained as below:

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

    To invoke it during loadevent, set autorun="true".

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

  2. If you're using PrimeFaces, use its <p:remoteCommand>.

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

    You can invoke it in JS as below:

    commandName();
    

    This however doesn't use JSF native jsf.ajax.request(), instead it uses PrimeFaces native jQuery (you know, PrimeFaces is a JSF component library on top of jQuery/UI).

    The parameters can be passed as below:

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

    And obtained as below:

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

    To invoke it during loadevent, set autoRun="true".

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

  3. If you're using OmniFaces, use its <o:commandScript>. The usage is exactly the same as with <h:commandScript>but then available for older JSF 2.x versions.

    Simply replace h:by o:in the first example. Historical note: the <h:commandScript>is entirely based off <o:commandScript>.


  4. Use the "hidden form" trick (actually, "hack" is given the ugliness a better wording).

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

    You can invoke it in JS as below:

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

    Note the importance of triggering onclick()instead of click()in case of <h:commandButton>. The onclick()immediately invokes the onclickfunction while the click()only triggers the "click" event on the element, which is not supported in IE. If you were using a <h:commandLink>, you can safely use click()instead.

    You can pass parameters via <h:inputHidden>in same form which you fill by JS beforehand. This is demonstrated in How to pass JavaScript variables as parameters to JSF action method?

    To invoke it during loadevent, consider putting it in <h:outputScript target="body">. The target="body"automatically puts the <script>in end of <body>, thus a $(document).ready()wrapper is unnecessary.

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

  5. Or, create a custom UIComponentwhich extends UICommandand generates the necessary JSF native jsf.ajax.request()call. As an example you could look at source codeof OmniFaces <o:commandScript>.

  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>