h: действие CommandButton в пользовательском интерфейсе: фрагмент иногда не выполняет действие

#jsf #jsf-2

#jsf #jsf-2

Вопрос:

Использование JSF 2.1

У нас есть форма, которая инкапсулирует блоки результатов поиска. У каждого блока есть кнопка «Удалить», которая связывается с поддержкой в области просмотра и удаляет блок (из компонента в области сеанса).

Визуально что-то вроде этого:

   -- group
    -- block (delete button)
      -- search result
    -- block 
      -- search result
    ...
  

Когда удаляется последний блок, вся группа исчезает.

В любом случае. Последующая реализация удаления работает нормально:

 <h:commandButton 
  styleClass="delete"
  action="#{backing.taBortFranTrafflista(sokning)}"
  value="#{backing.getText('trafflista.taBort')}"
  onclick="return confirm('#{backing.getText('FR100', sokning.sokbegrepp, backing.aktuelltAntalTraffar(sokning))}');"
  rendered="#{backing.javascriptEnabled}"
  disabled="#{commons.trafflistaLast}">
    <f:ajax render="@form" />
</h:commandButton>
  

Однако следующая реализация с подтверждением do в jQuery работает, но НЕ с последним результатом поиска, при котором действие (назначенное h:CommandButton) никогда не вызывается:

 <ui:fragment rendered="#{backing.javascriptEnabled}">
  <div id="dialog#{sokning.hashCode()}" title="Ta bort" class="dialog">
    <p>#{backing.getText('FR100', sokning.sokbegrepp, backing.aktuelltAntalTraffar(sokning))}</p>
    <h:commandButton 
      styleClass="delete dialog-button"
      action="#{backing.taBortFranTrafflista(sokning)}"
      value="#{backing.getText('trafflista.taBort')}"   
      onclick="closeDialog('dialog#{sokning.hashCode()}')"              
      disabled="#{commons.trafflistaLast}">
      <f:ajax render="@form" onerror="ajaxError"/>
    </h:commandButton>
    <input 
       type="submit" 
       data="dialog#{sokning.hashCode()}" 
       class="closeDialog dialog-button" 
       value="#{backing.getText('trafflista.avbryt')}" />
  </div>
  <ui:fragment rendered="#{not commons.trafflistaLast}">
    <input 
       type="submit" 
       data="dialog#{sokning.hashCode()}" 
       class="delete showDialog" 
       value="#{backing.getText('trafflista.taBort')}" />
  </ui:fragment>
  <ui:fragment rendered="#{commons.trafflistaLast}">
    <input 
       type="submit" 
       class="delete showDialog" 
       value="#{backing.getText('trafflista.taBort')}" 
       disabled="disabled"/>
  </ui:fragment>
</ui:fragment>
  

Комментарии:

1. Примечание стороны, проблема (с реализацией пользовательского интерфейса: фрагмент) не возникает, когда в группе есть только один блок результатов поиска. Странно.

2. В вашем коде я вижу какую-то странную вещь, которая мне не очень нравится. Первый #{backing.getText('trafflista.taBort')} . Ну, геттеры — это геттеры в java, и они используются для свойств. У них нет аргумента. Поэтому вам следует переименовать этот метод на что-то вроде textForArg(String arg) . Во-вторых, ваша кнопка должна вызывать поведение ajax или whole-submit? h:commandButton предназначен для работы как не-ajax, когда action указано. Тем не менее, вы создаете своего рода сочетание их обоих. Взгляните на документы о теге: docs.oracle.com/javaee/6/tutorial/doc/gkace.html

3. синтаксис get / set отмечен. Прочитайте документацию об атрибуте прослушивателя в f: ajax, а не в действии h: CommandButton . Не имеет никакого эффекта, в обоих случаях это частичный / ajax-запрос.

4. помещение ui:fragment вокруг h: CommandButton в рабочей реализации и перемещение отображаемого атрибута во фрагмент дает рабочий результат.

5. Проблема не возникает, если блоки удаляются от последнего к первому.

Ответ №1:

Причина, по которой faces-redirect=true работает, заключается в том, что компоненты DOM внутри формы совпадают с представлением сервера. Диалоговое окно jQuery отображалось за пределами формы внизу страницы. Выполнение render equal @all решило проблему. Другим решением было отобразить диалоговое окно внутри формы.