DataLoadCoordinator

DataLoadCoordinator facet is designed for triggering data loaders and for declarative linking of data loaders to data containers, visual components, and screen events.

Component’s XML-name: dataLoadCoordinator.

Basic Usage

To trigger all data loaders on screen’s BeforeShowEvent or fragment’s AttachEvent, just add DataLoadCoordinator with auto="true" to the screen XML descriptor:

<facets>
    <dataLoadCoordinator auto="true"/>
</facets>

Working Modes

You can configure DataLoadCoordinator to work in the automatic, manual or semi-automatic mode.

Automatic Mode

In this mode, DataLoadCoordinator relies on parameter names with particular prefixes. The prefix denotes a component that produces the parameter value and changes events.

By default, the parameter prefix is container_ for data containers and component_ for visual components. The componentPrefix and containerPrefix attributes allow you to use different prefixes.

With automatic configuration, the loader without parameters in its main query text (the static query not including query conditions) is refreshed on BeforeShowEvent in Screen or AttachEvent in ScreenFragment.

If you define a custom parameter (not container_ or component_) in the main query text, the automatic configuration will ignore the loader.

To refresh the ignored loader, simply assign parameter values and call load() on the loader object programmatically.

Usage example:

<window caption="msg://automaticModeScreen.caption"
        xmlns="http://jmix.io/schema/ui/window"
        xmlns:c="http://jmix.io/schema/ui/jpql-condition"> (1)
    <data readOnly="true">
        <collection id="citiesDc"
                    class="ui.ex1.entity.City">
            <fetchPlan extends="_base"/>
            <loader id="citiesDl">
                <query>
                    <![CDATA[select e from uiex1_City e]]> (2)
                    <condition>
                        <and>
                            <c:jpql>
                                <c:where>e.name like :component_nameField</c:where> (3)
                            </c:jpql>
                        </and>
                    </condition>
                </query>
            </loader>
        </collection>
        <collection id="customersDc"
                    class="ui.ex1.entity.Customer">
            <fetchPlan extends="_base"/>
            <loader id="customersDl" >
                <query>
                    <![CDATA[
                        select e from uiex1_Customer e
                            where e.city = :container_citiesDc
                    ]]> (4)
                </query>
            </loader>
        </collection>
    </data>
    <facets>
        <dataLoadCoordinator auto="true"/>
    </facets>
    <layout>
        <textField id="nameField"/>
    </layout>
</window>
1 Add XML schema for JPQL conditions.
2 There are no parameters in the query, so the citiesDl loader will be triggered on BeforeShowEvent.
3 The citiesDl loader will also be triggered on nameField component value change. As the condition uses the "like" clause, the value will be automatically wrapped in '(?i)% %' to provide the case-insensitive search.
4 The customersDl is triggered on the citiesDc data container item change.

Manual Mode

In this mode, the nested refresh elements define when the data loaders must be triggered.

Usage example:

<window caption="msg://manualModeScreen.caption"
        xmlns="http://jmix.io/schema/ui/window"
        xmlns:c="http://jmix.io/schema/ui/jpql-condition"> (1)
    <data readOnly="true">
        <collection id="citiesDc"
                    class="ui.ex1.entity.City">
            <fetchPlan extends="_base"/>
            <loader id="citiesDl">
                <query>
                    <![CDATA[select e from uiex1_City e]]>
                    <condition>
                        <and>
                            <c:jpql>
                                <c:where>e.name like :name</c:where>
                            </c:jpql>
                        </and>
                    </condition>
                </query>
            </loader>
        </collection>
        <collection id="customersDc"
                    class="ui.ex1.entity.Customer">
            <fetchPlan extends="_base"/>
            <loader id="customersDl" >
                <query>
                    <![CDATA[
                        select e from uiex1_Customer e
                            where e.city = :city
                    ]]>
                </query>
            </loader>
        </collection>
    </data>
    <facets>
        <dataLoadCoordinator>
            <refresh loader="citiesDl">
                <onScreenEvent type="Init"/> (2)
                <onComponentValueChanged component="nameField"
                                         likeClause="CASE_INSENSITIVE"
                                         param="name"/> (3)
            </refresh>
            <refresh loader="customersDl">
                <onContainerItemChanged container="citiesDc"
                                        param="city"/> (4)
            </refresh>
        </dataLoadCoordinator>
    </facets>
    <layout>
        <textField id="nameField"/>
    </layout>
</window>
1 Add XML schema for JPQL conditions.
2 The citiesDl loader will be triggered on InitEvent.
3 The citiesDl loader will also be triggered on the nameField component value change. The likeClause attribute causes the value to be wrapped in '(?i)% %' to provide the case-insensitive search.
4 The customersDl will be triggered on the citiesDc data container item change.

Semi-automatic Mode

When the auto attribute is set to true, and there are some manually configured triggers, DataLoadCoordinator will automatically configure all loaders having no manual configuration.

Usage example:

<window caption="msg://semiAutomaticModeScreen.caption"
        xmlns="http://jmix.io/schema/ui/window">
    <data readOnly="true">
        <collection id="brandsDc"
                    class="ui.ex1.entity.Brand">
            <fetchPlan extends="_base"/>
            <loader id="brandsDl">
                <query>
                    <![CDATA[select e from uiex1_Brand e]]>
                </query>
            </loader>
        </collection>
        <collection id="customersDc"
                    class="ui.ex1.entity.Customer">
            <fetchPlan extends="_base"/>
            <loader id="customersDl" >
                <query>
                    <![CDATA[
                        select e from uiex1_Customer e
                            where e.favouriteBrands = :container_brandsDc
                    ]]> (1)
                </query>
            </loader>
        </collection>
    </data>
    <facets>
        <dataLoadCoordinator auto="true">
            <refresh loader="brandsDl">
                <onScreenEvent type="AfterShow"/> (2)
            </refresh>
        </dataLoadCoordinator>
    </facets>
    <layout>
    </layout>
</window>
1 The customersDl is configured automatically and triggered on the brandsDc data container item change.
2 The brandsDl loader is configured manually and will be triggered on AfterShowEvent.

Attributes

  • auto - defines DataLoadCoordinator working mode. The default value is false.

  • componentPrefix - defines a prefix for parameters which refer to visual components from which DataLoadCoordinator will take parameter values in automatic mode. The default value is component_.

  • containerPrefix - defines a prefix for parameters which refer to data containers from which DataLoadCoordinator will take parameter values in automatic mode. The default value is container_.

Refresh Element

The refresh element allows you to define conditions for when a data loader must be refreshed.

The only attribute of this element is loader that defines the loader’s id.

The refresh element can have the following nested elements defining the triggering conditions:

  1. onComponentValueChanged - to trigger the loader when the value of a visual component is changed. It has the following attributes:

    • component - specifies the id of the visual component.

    • likeClause - if you use the like expression in query condition, you can define one of three possible search modes:

      • NONE - the default value.

      • CASE_SENSITIVE - uppercase and lowercase letters are treated as distinct.

      • CASE_INSENSITIVE - uppercase and lowercase letters are treated as equivalent.

    • param - specifies the query parameter name.

    <dataLoadCoordinator>
        <refresh loader="citiesDl">
            <onComponentValueChanged component="nameField"
                                     likeClause="CASE_SENSITIVE"
                                     param="name"/>
        </refresh>
    </dataLoadCoordinator>
  2. onContainerItemChanged - to trigger the loader when the current item in a data container is changed. It has the following attributes:

    • container - specifies the id of the data container.

    • param - specifies the query parameter name.

    <dataLoadCoordinator>
        <refresh loader="citiesDl">
            <onContainerItemChanged container="citiesDc"
                                    param="name"/>
        </refresh>
    </dataLoadCoordinator>
  3. onScreenEvent - to trigger the loader on a screen event. It has the following attribute:

    <dataLoadCoordinator>
        <refresh loader="citiesDl">
            <onScreenEvent type="BeforeShow"/>
        </refresh>
    </dataLoadCoordinator>
    onScreenEvent triggers are fired after listeners of the corresponding events defined in the screen controller with the @Subscribe annotation.
  4. onFragmentEvent - to trigger the loader on a fragment event. It has the following attribute:

    • type - defines the type of the screen fragment event. Possible values:

    <dataLoadCoordinator>
        <refresh loader="citiesDl">
            <onFragmentEvent type="Init"/>
        </refresh>
    </dataLoadCoordinator>

All XML Attributes

You can view and edit attributes applicable to the facet using the Jmix UI inspector panel of the Studio’s Screen Designer.

DataLoadCoordinator XML Elements

Refresh XML Attributes