События 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 , чтобы подписаться на событие фрагмента. |