Параметры обработчика A4J AJAX, установленные на стороне сервера Java

Как я могу добавить на стороне сервера то, что отправляется во все ответы ajax, чтобы я мог добавить свои собственные параметры?

Я расширил Richfaces JavaScript A4J.AJAX.finishRequest для запуска пользовательского события, и я хотел бы передать ему параметры с сервера:

var originalFinishRequest = A4J.AJAX.finishRequest;

A4J.AJAX.finishRequest = function(request) {
    var parameters = request.options.parameters;
    if (!request._oncomplete_aborted) {

       jQuery(document).trigger('onAutofocus',parameters);
    }
    originalFinishRequest(request);
};

Другой способ взглянуть на это: что отвечает серверная сторона на вызовы A4J.AJAX.Submit и как я могу обернуть вокруг этого свой собственный код?


Мое решение

Это то, что я в конечном итоге поместил в свой мастер-шаблон, основываясь на ответе BalusC:

<a4j:outputPanel ajaxRendered="true">
  <c:if test="#{not empty flowScope.autofocusSelectors}">
    <script>
      document.autofocusSelectors = #{flowScope.autofocusSelectors};
      console.log("BASE TEMPLATE: autofocus: (#{flowScope.autofocusSelectors})");
    </script>
  </c:if>
  <script>
    console.log("BASE TEMPLATE AJAX RENDER")
    //NB: autofocusSelectors not always set, and not only reason to autofocus
    jQuery(document).trigger('onAutofocus');
  </script>
</a4j:outputPanel>

person Sam Hasler    schedule 20.12.2012    source источник


Ответы (1)


Хотя это легко сделать в JSF2, который стандартизировал один и другое, это не совсем тривиально в RichFaces 3.x Ajax4jsf. Ответы Ajax обрабатываются org.ajax4jsf.Filter, который, в свою очередь, распространяется среди прочих BaseXmlFilter. Весь код написания ответа ajax находится там. Он не абстрагирован таким образом, что позволяет легко добавлять пользовательские теги/скрипты. В основном вам нужно скопировать и вставить и изменить его. Это просто не стоит усилий.

Более простой способ — просто автоматически ajax-рендерить часть <script>, содержащую нужные переменные в JS-варианте, чтобы свойства bean-компонента можно было назначить как глобальную переменную JS.

<a4j:outputPanel ajaxRendered="true">
    <script type="text/javascript">
        var parameters = <h:outputText value="#{bean.paramsAsJson}" />;
    </script>
</a4j:outputPanel>

(ajaxRendered="true" гарантирует, что это автоматически перерисовывается при каждом запросе ajax, поэтому вам не нужно явно добавлять его идентификатор в атрибут reRender какого-либо компонента A4J)

Где getParamsAsJson() просто возвращает строку Java в допустимом формате JSON, что-то вроде { foo: "foo", bar: "bar" }. Таким образом, вы можете просто использовать

A4J.AJAX.finishRequest = function(request) {
    if (!request._oncomplete_aborted) {
       jQuery(document).trigger('onAutofocus', parameters);
    }
    originalFinishRequest(request);
};

(обратите внимание, что request.options.parameters в основном содержит параметры запроса, которые отправляются клиентом при запуске запроса ajax, а не переменные, которые устанавливаются серверной стороной при возврате ответа ajax, поэтому было уже неправильно искать на нем)

Кроме того, я не совсем уверен, почему вы переопределяете A4J.AJAX.finishRequest вместо использования <a4j:status onstop="...">, но предполагая, что вы просто не знали об этом, вот как вы могли бы использовать его вместо этого:

<a4j:status onstop="jQuery(document).trigger('onAutofocus', parameters)" />
person BalusC    schedule 03.01.2013
comment
Я пытался расширить request.options.parameters дополнительными параметрами на стороне сервера, так как это казалось более аккуратным, чем выбор глобальных переменных JS, поскольку я не хотел вставлять скрипты везде, где я это использую. Я не знал о методе ajaxRendered, но если я смогу использовать его в своем базовом шаблоне, это будет хорошим решением. - person Sam Hasler; 03.01.2013
comment
request.options.parameters представляет карту параметров HTTP-запроса, которая уже заполнена перед отправкой запроса ajax. Это определенно не изменчиво со стороны сервера. - person BalusC; 03.01.2013
comment
Я знал о a4j:status onstop, но он уже используется в коде для других целей, и я считаю, что его можно определить только один раз. Я также хочу избежать добавления тегов на каждой странице. - person Sam Hasler; 03.01.2013
comment
Рассмотрите возможность использования Facelets вместо JSP, тогда у вас может быть один мастер-шаблон. Но, скорее всего, это не стоит усилий для такого устаревшего приложения. - person BalusC; 03.01.2013
comment
может быть, это потому, что я фронтенд-разработчик, пытающийся получить вещи на стороне сервера, чтобы облегчить себе жизнь, поэтому я не знаю ричфейсов так хорошо, как должен (пока), но я не уверен, как я произвел впечатление Я не использовал фейслеты. - person Sam Hasler; 03.01.2013
comment
Если бы вы использовали Facelets, вы бы не сказали Я также хочу избежать необходимости добавлять теги на каждую страницу, что является одним из основных преимуществ использования JSP и одной из главных причин использования Facelets. - person BalusC; 03.01.2013
comment
Думаю, я имел в виду лицевую панель вместо страницы, если это имеет смысл. Я просто хотел, чтобы в фейслетах было одно место, управляющее настройкой параметров. Теперь я добавил outputPanel в свой базовый шаблон, который вставляет скрипт, если установлены какие-либо переменные потока, которые я хочу передать обработчикам событий JavaScript. Я думаю, что я, вероятно, также могу запускать обработчики событий оттуда, поэтому мне больше не нужно будет переопределять A4J.AJAX.finishRequest. Спасибо! - person Sam Hasler; 04.01.2013
comment
Пожалуйста. Возвращаясь к шаблонам, если вы действительно используете Facelets, возможно, вы упустили одну из его самых больших возможностей. Проверьте второй пример в этом ответе: stackoverflow.com/questions/4792862/ Вы могли просто использовать <a4j:status> на главной странице шаблона. - person BalusC; 04.01.2013
comment
Именно так мы делаем шаблоны. Я бы использовал <a4j:status>, если бы мне не нужно было <c:if test="#{not empty param}">. Я добавил свое решение вопроса. - person Sam Hasler; 07.01.2013