Как вызвать управляемый JSF bean в событии HTML DOM с использованием собственного JavaScript?

Мне нужно выполнить управляемый JSF метод действия bean, используя ajax во время события HTML DOM load, похожее на jQuery $(document).ready(function() { $.ajax(...) }). Я могу использовать только JavaScript, созданный JSF в этом проекте. Есть ли способ сделать это в родной JSF? Какое событие я могу использовать или какую функцию ajax JSF можно использовать?

Я использую 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();
    

    Чтобы вызвать его во время события 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 jsf.ajax.request(), вместо этого он использует собственный JQuery для PrimeFaces (вы знаете, PrimeFaces - это библиотека компонентов JSF поверх jQuery/UI).

    Чтобы вызвать его во время события load, установите autorun="true".

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

  3. Если вы используете OmniFaces, используйте его <o:commandScript>. Использование точно такое же, как с <h:commandScript> но затем доступно для более старых версий JSF 2.x.

    Просто замените h: на o: в первом примере. Историческая справка: <h:commandScript> полностью основан на <o:commandScript>.


  4. Используйте трюк с "скрытой формой" (на самом деле "хак" дает уродству лучшую формулировку).

    <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>. onclick() немедленно вызывает функцию onclick то время как click() запускает только событие "click" для элемента, которое не поддерживается в IE. Если вы использовали <h:commandLink>, вы можете безопасно использовать click().

    Чтобы вызвать его во время события load, <h:outputScript target="body"> поместить его в <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.ajax.request() JSF jsf.ajax.request(). В качестве примера вы можете посмотреть исходный код OmniFaces <o:commandScript>.