h: commandLink f: действие ajax не вызывается, когда страница имеет f: viewParam required = true

В моем веб-приложении JSF2 (mojarra 2.1.20) наблюдается странное поведение на странице, содержащей компонент со следующим фрагментом:

<h:commandLink ... action="#{cc.attrs.bean.next}">
    <f:ajax execute="@this" render=":#{cc.clientId}" />
</h:commandLink>

Действие next() вызывается не всегда. Я обнаружил, что проблема по какой-то причине связана с идентификатором параметра URL:

<f:metadata>
    <f:viewParam name="id" value="#{torneoBean.idParam}" required="true" />
</f:metadata>

Когда я вставляю viewParam выше, возникает проблема. Но я не могу избавиться от него. При отладке запроса ajax кажется, что вызывается запуск, успех, полная последовательность событий (без ошибок), компоненты для рендеринга отображаются правильно, но действие не запускается. Есть ли способ отладить эту ситуацию и выяснить, что является основной причиной проблемы?


person maxqua72    schedule 06.04.2013    source источник


Ответы (1)


Очевидно, вы не прикрепили <h:message(s)> к <f:viewParam id="torneo_id"> и/или не обновляете его при каждом запросе ajax. В противном случае вы бы увидели на нем требуемую ошибку проверки. Конкретная проблема по существу рассматривается в пункте 3 действия commandButton/commandLink/ajax. Метод /listener не вызван или входное значение не обновлено.

Что касается причины, то <f:viewParam> выполняется для каждого HTTP-запроса, а также для обратных передач ajax. Когда запрос ajax отправляется, требуемый параметр запроса больше не присутствует в текущем запросе, и, следовательно, <f:viewParam> не проходит требуемую проверку.

Для этого есть несколько решений:

  1. Сохраните параметр запроса для последующего запроса с помощью <f:param> в компоненте команды.

    <h:commandLink ...>
        ...
        <f:param name="id" value="#{param.id}" />
    </h:commandLink>
    
  2. Сделайте это обязательным только во время не-постбэка. Это работает, только если страница изначально открыта запросом GET. Однако, если он открывается с помощью навигации без перенаправления, он все равно не будет работать.

    <f:viewParam ... required="#{not facesContext.postback}" />
    
  3. Замените <f:viewParam> на служебную библиотеку JSF OmniFaces, <o:viewParam>. Он неявно отключает required="true" для обратных передач, чтобы вы могли продолжать использовать те же атрибуты.

    <o:viewParam ... required="true" />
    
person BalusC    schedule 07.04.2013
comment
Спасибо BalusC! Решение № 2 решает мою проблему, но как вообще я могу отлаживать подобные проблемы? h:message, безусловно, мог бы помочь, но мог ли я использовать фазовый прослушиватель, чтобы отловить эту проблему (своего рода детектор неправильного поведения) и все другие проблемы, связанные с невызванными действиями? - person maxqua72; 07.04.2013
comment
Слушатель фазы, который регистрирует текущую фазу, действительно намекнул бы, что значения модели обновления и фазы вызова приложения были пропущены. Кроме того, разве вы не заметили, что JSF регистрирует стоящие в очереди, но не отображаемые сообщения? По крайней мере, Мохарра так делает. В крайнем случае, установка точки останова в FacesServlet#service() и продвижение формы также должны дать много понимания. Чем больше вы это делаете, тем лучше вы понимаете жизненный цикл JSF и тем легче выявляете потенциальные проблемы. - person BalusC; 07.04.2013
comment
Странно, что в логе не прослеживается ни ошибок, ни предупреждений о поставленных в очередь и неотображаемых сообщениях. Лог чистый, поэтому и спросил способ отладки. Это определенно будет полезно для таких обстоятельств. - person maxqua72; 07.04.2013