3.5.4.3. DataLoadCoordinator

Невизуальный компонент DataLoadCoordinator предназначен для декларативного связывания загрузчиков данных с контейнерами данных, визуальными компонентами и событиями экрана. Он может работать в двух режимах:

  • В автоматическом режиме компонент полагается на имена параметров, имеющие специальные префиксы. Префикс указывает, какой компонент является источником значения параметра и событий его изменения. Если у загрузчика нет параметрова в тексте запроса (при этом параметры могут быть в условиях), то он срабатывает по событию BeforeShowEvent в Screen или по событию AttachEvent в ScreenFragment.

    По умолчанию используется префикс container_ для контейнеров данных и component_ для визуальных компонентов.

  • В ручном режиме связи указываются в XML-разметке компонента или через его API.

Возможен также полуавтоматический режим, при котором некоторые связи задаются явно, а остальные конфигурируются автоматически.

При использовании DataLoadCoordinator в экране, аннотация @LoadDataBeforeShow на контроллере экрана не оказывает эффекта: загрузка данных полностью управляется компонентом DataLoadCoordinator и кастомными обработчиками событий, если они определены.

Ниже приведены примеры использования компонента.

  1. Автоматическая конфигурация. Атрибут auto установлен в true.

    <window xmlns="http://schemas.haulmont.com/cuba/screen/window.xsd"
            xmlns:c="http://schemas.haulmont.com/cuba/screen/jpql_condition.xsd" ...>
        <data readOnly="true">
            <collection id="ownersDc" class="com.company.demo.entity.Owner" view="owner-view">
                <loader id="ownersDl">
                    <query>
                        <![CDATA[select e from demo_Owner e]]> (1)
                        <condition>
                            <c:jpql>
                                <c:where>e.category = :component_categoryFilterField</c:where> (2)
                            </c:jpql>
                            <c:jpql>
                                <c:where>e.name like :component_nameFilterField</c:where> (3)
                            </c:jpql>
                        </condition>
                    </query>
                </loader>
            </collection>
            <collection id="petsDc" class="com.company.demo.entity.Pet">
                <loader id="petsDl">
                    <query><![CDATA[select e from demo_Pet e where e.owner = :container_ownersDc]]></query> (4)
                </loader>
            </collection>
        </data>
        <facets>
            <dataLoadCoordinator auto="true"/>
        </facets>
        <layout>
            <pickerField id="categoryFilterField" metaClass="demo_OwnerCategory"/>
            <textField id="nameFilterField"/>
    1 - в запросе нет параметров, поэтому загрузчик ownersDl сработает на событие экрана BeforeShowEvent.
    2 - загрузчик ownersDl также сработает на изменение значения компонента categoryFilterField.
    3 - загрузчик ownersDl также сработает на изменение значения компонента nameFilterField. Так как условие использует оператор like, значение будет автоматически завернуто в '(?i)% %' для того, чтобы обеспечить нечувствительный к регистру поиск.
    4 - загрузчик petsDl сработает при смене выбранной сущности в контейнере ownersDc.
  2. Ручная конфигурация. Атрибут auto отсутствует или установлен в false, вложенные элементы определяют, когда должны сработать загрузчики.

    <window xmlns="http://schemas.haulmont.com/cuba/screen/window.xsd"
            xmlns:c="http://schemas.haulmont.com/cuba/screen/jpql_condition.xsd" ...>
        <data readOnly="true">
            <collection id="ownersDc" class="com.company.demo.entity.Owner" view="owner-view">
                <loader id="ownersDl">
                    <query>
                        <![CDATA[select e from demo_Owner e]]>
                        <condition>
                            <c:jpql>
                                <c:where>e.category = :category</c:where>
                            </c:jpql>
                            <c:jpql>
                                <c:where>e.name like :name</c:where>
                            </c:jpql>
                        </condition>
                    </query>
                </loader>
            </collection>
            <collection id="petsDc" class="com.company.demo.entity.Pet">
                <loader id="petsDl">
                    <query><![CDATA[select e from demo_Pet e where e.owner = :owner]]></query>
                </loader>
            </collection>
        </data>
        <facets>
            <dataLoadCoordinator>
                <refresh loader="ownersDl"
                         onScreenEvent="Init"/> (1)
    
                <refresh loader="ownersDl" param="category"
                         onComponentValueChanged="categoryFilterField"/> (2)
    
                <refresh loader="ownersDl" param="name"
                         onComponentValueChanged="nameFilterField" likeClause="CASE_INSENSITIVE"/> (3)
    
                <refresh loader="petsDl" param="owner"
                         onContainerItemChanged="ownersDc"/> (4)
            </dataLoadCoordinator>
        </facets>
        <layout>
            <pickerField id="categoryFilterField" metaClass="demo_OwnerCategory"/>
            <textField id="nameFilterField"/>
    1 - загрузчик ownersDl сработает на событие экрана InitEvent.
    2 - загрузчик ownersDl также сработает на изменение значения компонента categoryFilterField.
    3 - загрузчик ownersDl также сработает на изменение значения компонента nameFilterField. Атрибут likeClause приводит к заворачиванию значения в '(?i)% %' для того, чтобы обеспечить нечувствительный к регистру поиск.
    4 - загрузчик petsDl сработает при смене выбранной сущности в контейнере ownersDc.
  3. Полуавтоматическая конфигурация. Когда атрибут auto установлен в true и объявлены некоторые вручную сконфигурированные связи, компонент автоматически сконфигурирует все загрузчики, для которых не указано ни одной связи вручную.

    <window xmlns="http://schemas.haulmont.com/cuba/screen/window.xsd" ...>
        <data readOnly="true">
            <collection id="ownersDc" class="com.company.demo.entity.Owner" view="owner-view">
                <loader id="ownersDl">
                    <query>
                        <![CDATA[select e from demo_Owner e]]>
                    </query>
                </loader>
            </collection>
            <collection id="petsDc" class="com.company.demo.entity.Pet">
                <loader id="petsDl">
                    <query><![CDATA[select e from demo_Pet e where e.owner = :container_ownersDc]]></query> (1)
                </loader>
            </collection>
        </data>
        <facets>
            <dataLoadCoordinator auto="true">
                <refresh loader="ownersDl" onScreenEvent="Init"/> (2)
            </dataLoadCoordinator>
        </facets>
    1 - загрузчик petsDl сконфигурирован автоматически и сработает при смене выбранной сущности в контейнере ownersDc.
    2 - загрузчик ownersDl сконфигурирован вручную и сработает на событие экрана InitEvent.