В этой статье я хотел бы остановиться на очень распространенном случае использования af: popup, содержащем af: диалог с входными компонентами внутри. Есть несколько подводных камней, на которые мы должны обратить внимание при реализации этого варианта использования.
Давайте рассмотрим простой пример:
| 1 2 3 4 5 6 7 8 | <af:popupid="p1"contentDelivery="lazyUncached">            <af:dialogid="d2"title="Dialog">     <af:inputTextvalue="#{TheBean.firstName}"label="First Name"id="it1"/>     <af:inputTextvalue="#{TheBean.lastName}"label="Last Name"id="it2"/>  </af:dialog>  </af:popup> | 
Самым интересным здесь является свойство contentDelivery всплывающего окна, для которого установлено значение lazyUncached . Это предотвращает кэширование всплывающих входных значений и заставляет его получать значения из модели при каждом запросе вместо использования значений из кэша.
Давайте сделаем пример немного сложнее. В установщике lastName мы собираемся сгенерировать исключение:
| 1 2 3 4 | publicvoidsetLastName(String lastName) throwsException {            this.lastName = lastName;            thrownewException("This last name is bad");} | 
Итак, очевидно, что если мы попытаемся отправить диалог, мы получим следующее:
 
  Входные значения не могут быть переданы в модель, и они будут сохранены в локальных значениях входных компонентов.  Эти локальные значения не будут очищены, даже если мы нажмем кнопку « Отмена» , и эти значения будут использоваться во время запроса подпоследовательности.  Чтобы предотвратить это, мы должны установить свойство resetEditableValues для всплывающего окна в whenCanceled .  Как это: 
| 1 2 3 4 5 6 7 8 9 | <af:popupid="p1"contentDelivery="lazyUncached"                  resetEditableValues="whenCanceled">  <af:dialogid="d2"title="Dialog">     <af:inputTextvalue="#{TheBean.firstName}"label="First Name"id="it1"/>     <af:inputTextvalue="#{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:popupid="p1"contentDelivery="lazyUncached"                  resetEditableValues="whenCanceled"                  binding="#{TheBean.popup}">  <af:dialogid="d2"title="Dialog"type="none">     <af:inputTextvalue="#{TheBean.firstName}"label="First Name"id="it1"/>     <af:inputTextvalue="#{TheBean.lastName}"label="Last Name"id="it2"/>     <f:facetname="buttonBar">        <af:panelGroupLayoutlayout="horizontal"id="pgl1">          <af:buttontext="Ok"id="b2"                     actionListener="#{TheBean.buttonActionListener}"/>          <af:buttontext="Cancel"id="b3"immediate="true"                     actionListener="#{TheBean.buttonActionListener}"/>        </af:panelGroupLayout>       </f:facet>  </af:dialog>    </af:popup> | 
Итак, есть две пользовательские кнопки «Ok» и «Cancel» со следующим actionListener :
| 1 2 3 | publicvoidbuttonActionListener(ActionEvent actionEvent) {    getPopup().hide();} | 
В этом случае resetEditableValues не работает, и локальные значения компонентов ввода не будут очищены при нажатии кнопки Отмена . Есть несколько вариантов решения этой проблемы.
Первый — добавить af: resetListener к кнопке Cancel:
| 1 2 3 4 |           <af:buttontext="Cancel"id="b3"immediate="true"                     actionListener="#{TheBean.buttonActionListener}">               <af:resetListenertype="action"/>          </af:button> | 
Второй вариант — отменить всплывающее окно, а не просто скрыть его в слушателе действия кнопки «Отмена»:
| 1 2 3 4 |   <af:buttontext="Ok"id="b2"             actionListener="#{TheBean.buttonActionListener}"/>  <af:buttontext="Cancel"id="b3"immediate="true"             actionListener="#{TheBean.cancelButtonActionListener}"/> | 
| 1 2 3 | publicvoidcancelButtonActionListener(ActionEvent actionEvent) {   getPopup().cancel();} | 
Это оно!
| Ссылка: | ADF: Popup, Dialog и Input Components от нашего партнера JCG Евгения Федоренко в блоге ADF Practice . |