События ScreenFragment
В данном разделе описаны события жизненного цикла фрагмента, на которые можно подписаться в контроллерах фрагментов.
InitEvent
Это событие посылается, когда контроллер фрагмента и все его декларативно заданные компоненты созданы, а инжекция зависимостей завершена. Вложенные фрагменты на этом этапе еще не инициализированы. Некоторые визуальные компоненты инициализированы не полностью: например, кнопки еще не связаны с действиями. Если фрагмент подключается к включающему экрану декларативно в XML, данное событие посылается после InitEvent контроллера включающего экрана. В противном случае событие посылается, когда фрагмент подключается к дереву компонентов включающего экрана.
AfterInitEvent
Это событие посылается, когда контроллер фрагмента и все его декларативно заданные компоненты созданы, инжекция зависимостей завершена, и все компоненты завершили свою внутреннюю процедуру инициализации. Вложенные фрагменты (при наличии) опубликовали свои события InitEvent и AfterInitEvent. В слушателе этого события можно создавать визуальные компоненты и компоненты данных, а также выполнить дополнительную инициализацию, если она зависит от инициализации вложенных фрагментов.
AttachEvent
Это событие посылается после того, как фрагмент добавлен к дереву компонентов включающего экрана. В этот момент фрагмент полностью инициализирован, события InitEvent и AfterInitEvent отосланы. В слушателе данного события можно обращаться к включающему экрану, используя методы getHostScreen() и getHostController().
Пример подписки на AttachEvent:
@UiController("sample_AddressFragment")
@UiDescriptor("address-fragment.xml")
public class AddressFragment extends ScreenFragment {
private static final Logger log = LoggerFactory.getLogger(AddressFragment.class);
@Subscribe
private void onAttach(AttachEvent event) {
Screen hostScreen = getHostScreen();
FrameOwner hostController = getHostController();
log.info("onAttach to screen {} with controller {}", hostScreen, hostController);
}
DetachEvent
Это событие посылается после того, как фрагмент программно удален из дерева компонентов включающего экрана. В слушателе данного события нельзя обращаться к включающему экрану.
Подписка на события включающего экрана
В контроллере фрагмента можно также подписаться на события включающего экрана путем указания значения PARENT_CONTROLLER в атрибуте target аннотации, например:
@Subscribe(target = Target.PARENT_CONTROLLER)
private void onBeforeShowHost(Screen.BeforeShowEvent event) {
// ...
}
Таким способом можно обработать любое событие, в том числе InitEntityEvent, посылаемое экранами редактирования.
Подписка на события фрагмента во включающем экране
В контроллере включающего экрана можно также подписаться на события контроллера фрагмента. Ниже приведен пример подписки на специальное событие, отправляемое фрагментом при изменении значения его компонента.
В контроллере фрагмента создайте класс события и метод для регистрации слушателей этого события:
public static class CountryChangeEvent extends EventObject { (1)
private Country country;
public CountryChangeEvent(Object source, Country value) {
super(source);
country = value;
}
public Country getCountry() {
return country;
}
}
public Subscription addChangeListener(Consumer<CountryChangeEvent> listener) {
return getEventHub().subscribe(CountryChangeEvent.class, listener); (2)
}
@Subscribe("countryField")
public void onCountryFieldValueChange(HasValue.ValueChangeEvent<Country> event) {
fireEvent(CountryChangeEvent.class, new CountryChangeEvent(this, event.getValue())); (3)
}
| 1 | Создайте специальный класс события на основе EventObject. |
| 2 | Создайте метод для регистрации слушателей данного события. |
| 3 | Событие посылается с помощью метода fireEvent(). |
Теперь можно декларативно подписаться на это событие фрагмента в контроллере включающего экрана следующим образом:
@Autowired
private Notifications notifications;
@Subscribe(id = "addressFragment", target = Target.CONTROLLER) (1)
protected void onChange(AddressFragment.CountryChangeEvent event) {
notifications.create()
.withCaption("Changed country: " + event.getCountry())
.show();
}
| 1 | Используйте id фрагмента и Target.CONTROLLER, чтобы подписаться на событие фрагмента. |