Статьи

ADF: всплывающее окно, диалоговое окно и компоненты ввода

В этой статье я хотел бы остановиться на очень распространенном случае использования af: popup, содержащем af: диалог с входными компонентами внутри. Есть несколько подводных камней, на которые мы должны обратить внимание при реализации этого варианта использования.

Давайте рассмотрим простой пример:

1
2
3
4
5
6
7
8
<af:popup id="p1" contentDelivery="lazyUncached">
           
  <af:dialog id="d2" title="Dialog" >
     <af:inputText value="#{TheBean.firstName}" label="First Name" id="it1"/>
     <af:inputText value="#{TheBean.lastName}" label="Last Name" id="it2"/>
  </af:dialog>
   
</af:popup>

Самым интересным здесь является свойство contentDelivery всплывающего окна, для которого установлено значение lazyUncached . Это предотвращает кэширование всплывающих входных значений и заставляет его получать значения из модели при каждом запросе вместо использования значений из кэша.

Давайте сделаем пример немного сложнее. В установщике lastName мы собираемся сгенерировать исключение:

1
2
3
4
public void setLastName(String lastName) throws Exception {       
    this.lastName = lastName;       
    throw new Exception("This last name is bad");
}

Итак, очевидно, что если мы попытаемся отправить диалог, мы получим следующее:

Снимок экрана 2014-08-04 в 19.09.13
Входные значения не могут быть переданы в модель, и они будут сохранены в локальных значениях входных компонентов. Эти локальные значения не будут очищены, даже если мы нажмем кнопку « Отмена» , и эти значения будут использоваться во время запроса подпоследовательности. Чтобы предотвратить это, мы должны установить свойство resetEditableValues для всплывающего окна в whenCanceled . Как это:

1
2
3
4
5
6
7
8
9
<af:popup id="p1" contentDelivery="lazyUncached"
                  resetEditableValues="whenCanceled">
 
  <af:dialog id="d2" title="Dialog" >
     <af:inputText value="#{TheBean.firstName}" label="First Name" id="it1"/>
     <af:inputText value="#{TheBean.lastName}" label="Last Name" id="it2"/>
  </af:dialog
   
</af:popup>

Давайте рассмотрим пример диалога af: с пользовательскими кнопками:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
<af:popup id="p1" contentDelivery="lazyUncached"
                  resetEditableValues="whenCanceled"
                  binding="#{TheBean.popup}">
 
  <af:dialog id="d2" title="Dialog" type="none">
     <af:inputText value="#{TheBean.firstName}" label="First Name" id="it1"/>
     <af:inputText value="#{TheBean.lastName}" label="Last Name" id="it2"/>
     <f:facet name="buttonBar">
        <af:panelGroupLayout layout="horizontal" id="pgl1">
          <af:button text="Ok" id="b2"
                     actionListener="#{TheBean.buttonActionListener}"/>
          <af:button text="Cancel" id="b3" immediate="true"
                     actionListener="#{TheBean.buttonActionListener}"/>
        </af:panelGroupLayout
     </f:facet>
 
  </af:dialog
   
</af:popup>

Итак, есть две пользовательские кнопки «Ok» и «Cancel» со следующим actionListener :

1
2
3
public void buttonActionListener(ActionEvent actionEvent) {
    getPopup().hide();
}

В этом случае resetEditableValues не работает, и локальные значения компонентов ввода не будут очищены при нажатии кнопки Отмена . Есть несколько вариантов решения этой проблемы.

Первый — добавить af: resetListener к кнопке Cancel:

1
2
3
4
          <af:button text="Cancel" id="b3" immediate="true"
                     actionListener="#{TheBean.buttonActionListener}">
               <af:resetListener type="action"/>
          </af:button>

Второй вариант — отменить всплывающее окно, а не просто скрыть его в слушателе действия кнопки «Отмена»:

1
2
3
4
  <af:button text="Ok" id="b2"
             actionListener="#{TheBean.buttonActionListener}"/>
  <af:button text="Cancel" id="b3" immediate="true"
             actionListener="#{TheBean.cancelButtonActionListener}"/>
1
2
3
public void cancelButtonActionListener(ActionEvent actionEvent) {
   getPopup().cancel();
}

Это оно!

Ссылка: ADF: Popup, Dialog и Input Components от нашего партнера JCG Евгения Федоренко в блоге ADF Practice .