События 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, посылаемое экранами редактирования.

Подписка на события фрагмента во включающем экране

В контроллере включающего экрана можно также подписаться на события контроллера фрагмента. Ниже приведен пример подписки на специальное событие, отправляемое фрагментом при изменении значения его компонента.

В контроллере фрагмента создайте класс события и метод для регистрации слушателей этого события:

AddressFragment.java
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().

Теперь можно декларативно подписаться на это событие фрагмента в контроллере включающего экрана следующим образом:

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