Разработчик приложения может реализовывать слушатели как классы или как методы Managed-бина. Если слушатель является методом Managed-бина, автор страницы ссылается на метод либо из атрибута valueChangeListener компонента, либо из его атрибута actionListener. Если слушатель является классом, автор страницы может ссылаться на слушателя либо из тега f:valueChangeListener, либо из тега f:actionListener и вкладывать внутрь тега компонента для регистрирации слушателя в компоненте.
В этом разделе объясняется, как зарегистрировать слушатель изменения значения NameChanged и слушатель действия BookChange в компонентах. В примере Duke's Bookstore участвуют оба этих слушателя.
Регистрация слушателя изменения значения в компоненте
Автор страницы может зарегистрировать реализацию ValueChangeListener в компоненте, который реализует EditableValueHolder, вложив тег f:valueChangeListener в тег компонента на странице. Тег f:valueChangeListener поддерживает атрибуты, показанные в таблице 11-5, один из которых обязательно должен использоваться.
Таблица 11-5 Атрибуты для тега f:valueChangeListener
Атрибут |
Описание |
type
|
Ссылается на полное имя класса реализации ValueChangeListener. Может принимать литерал или выражение значения. |
binding
|
Ссылается на объект, который реализует ValueChangeListener. Может принимать только выражение значения, которое должно указывать на свойство Managed-бина, принимающее и возвращающее реализацию ValueChangeListener. |
В следующем примере показан слушатель изменения значения, зарегистрированный в компоненте:
<h:inputText id="name"
size="30"
value="#{cashierBean.name}"
required="true"
requiredMessage="#{bundle.ReqCustomerName}">
<f:valueChangeListener
type="javaeetutorial.dukesbookstore.listeners.NameChanged" />
</h:inputText>
В этом примере атрибут type основного тега указывает кастомный слушатель NameChanged как реализацию ValueChangeListener, зарегистрированную в name компонента.
После обработки этого тега и валидации локальных значений соответствующий ему компонент поставит ValueChangeEvent в очередь для компонента, связанного с указанным ValueChangeListener.
Регистрация слушателя действий в компоненте
Автор страницы может зарегистрировать реализацию ActionListener в командном компоненте, вложив тег f:actionListener в тег компонента на странице. Аналогично тегу f:valueChangeListener, тег f:actionListener поддерживает оба атрибута: type и binding. Один из этих атрибутов должен использоваться для ссылки на слушатель действия.
Вот пример тега h:commandLink, который ссылается на реализацию ActionListener:
<h:commandLink id="Duke" action="bookstore">
<f:actionListener
type="javaeetutorial.dukesbookstore.listeners.LinkBookChangeListener" />
<h:outputText value="#{bundle.Book201}"/>
</h:commandLink>
В дополнение к тегу actionListener, который позволяет вам зарегистрировать пользовательский слушатель в компоненте, библиотека основных тегов включает тег f:setPropertyActionListener. Этот тег используется для регистрации специального слушателя действий в объекте ActionSource, связанном с компонентом. Когда компонент активирован, слушатель сохраняет объект, на который ссылается атрибут value, в объект, на который ссылается атрибут target.
Страница bookcatalog.xhtml приложения Duke's Bookstore использует f:setPropertyActionListener с двумя компонентами: компонентом h:commandLink, используемым для ссылки на страницу bookdetails.xhtml и компонентом h:commandButton, используемым для добавления книги в корзину:
<h:dataTable id="books"
value="#{store.books}"
var="book"
headerClass="list-header"
styleClass="list-background"
rowClasses="list-row-even, list-row-odd"
border="1"
summary="#{bundle.BookCatalog}" >
...
<h:column>
<f:facet name="header">
<h:outputText value="#{bundle.ItemTitle}"/>
</f:facet>
<h:commandLink action="#{catalog.details}"
value="#{book.title}">
<f:setPropertyActionListener target="#{requestScope.book}"
value="#{book}"/>
</h:commandLink>
</h:column>
...
<h:column>
<f:facet name="header">
<h:outputText value="#{bundle.CartAdd}"/>
</f:facet>
<h:commandButton id="add"
action="#{catalog.add}"
value="#{bundle.CartAdd}">
<f:setPropertyActionListener target="#{requestScope.book}"
value="#{book}"/>
</h:commandButton>
</h:column>
Теги h:commandLink и h:commandButton находятся внутри тега h:dataTable, который перебирает список книг. Атрибут var ссылается на одну книгу в списке.
Объект, на который ссылается атрибут var тега h:dataTable, находится в области видимости страницы. Однако в этом случае вам нужно поместить этот объект в область запроса, чтобы при активации пользователем компонента commandLink для перехода на bookdetails.xhtml или компонента commandButton для перехода на bookcatalog.xhtml данные книги стали доступны для этих страниц. Следовательно, тег f:setPropertyActionListener используется для установки объекта текущей книги в область запроса, когда активирован компонент commandLink или commandButton.
В предыдущем примере атрибут value тега f:setPropertyActionListener ссылается на объект book. Атрибут target тега f:setPropertyActionListener ссылается на выражение значения requestScope.book, в котором содержится объект book атрибута value, когда активируется компонент commandLink или commandButton.