3.11.2. Расширение экранов

Платформа позволяет создавать новые XML-дескрипторы экранов путем наследования от существующих.

Наследование XML выполняется путем указания в корневом элементе window атрибута extends, содержащего путь к базовому дескриптору.

Правила переопределения элементов XML экрана:

  • Если в расширяющем дескрипторе указан некоторый элемент, в базовом дескрипторе будет произведен поиск соответствующего элемента по следующему алгоритму:

    • Если в переопределяющем элементе указан атрибут id, ищется соответствующий элемент с таким же id.

    • Если поиск дал результат, то найденный элемент переопределяется.

    • Если поиск не дал результата, то определяется, сколько в базовом дескрипторе элементов по данному пути и с данным именем. Если ровно один - он переопределяется.

    • Если поиск не дал результата, и в базовом дескрипторе по данному пути с данным именем нет элементов, либо их больше одного, добавляется новый элемент.

  • В переопределяемом либо добавляемом элементе устанавливается текст из расширяющего элемента.

  • В переопределяемый либо добавляемый элемент копируются все атрибуты из расширяющего элемента. При совпадении имени атрибута значение берется из расширяющего элемента.

  • Добавление нового элемента по умолчанию производится в конец списка соседних элементов. Чтобы добавить новый элемент в начало или с произвольным индексом, необходимо выполнить следующее:

    • определить в расширяющем дескрипторе дополнительный namespace: xmlns:ext="http://schemas.haulmont.com/cuba/window-ext.xsd"

    • добавить в расширяющий элемент атрибут ext:index с желаемым индексом, например: ext:index="0".

Для отладки преобразования дескрипторов можно включить вывод в журнал сервера результирующего XML. Делается это путем указания уровня TRACE для логгера com.haulmont.cuba.gui.xml.XmlInheritanceProcessor в файле конфигурации Logback.

Расширение устаревших экранов

Фреймворк содержит некоторое количества экранов, реализованных на legacy API для обратной совместимости. Ниже рассмотрены примеры расширения экранов сущности User, входящей в состав подсистемы безопасности.

Создайте XML-дескриптор браузера сущности ExtUser:

ext-user-browse.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
        xmlns:ext="http://schemas.haulmont.com/cuba/window-ext.xsd"
        extends="/com/haulmont/cuba/gui/app/security/user/browse/user-browse.xml">
    <layout>
        <groupTable id="usersTable">
            <columns>
                <column ext:index="2" id="address"/>
            </columns>
        </groupTable>
    </layout>
</window>

В данном примере дескриптор унаследован от стандартного браузера сущностей User фреймворка, и в таблицу добавлена колонка address с индексом 2, т.е. отображающаяся после login и name.

Зарегистрируйте новый экран в screens.xml с теми же идентификаторами, которые использовались для базового экрана. После этого новый экран будет повсеместно вызываться взамен старого.

<screen id="sec$User.browse"
        template="com/sample/sales/gui/extuser/extuser-browse.xml"/>
<screen id="sec$User.lookup"
        template="com/sample/sales/gui/extuser/extuser-browse.xml"/>

Аналогично создайте экран редактирования:

ext-user-edit.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
        xmlns:ext="http://schemas.haulmont.com/cuba/window-ext.xsd"
        extends="/com/haulmont/cuba/gui/app/security/user/edit/user-edit.xml">
    <layout>
        <groupBox id="propertiesBox">
            <grid id="propertiesGrid">
                <rows>
                    <row id="propertiesRow">
                        <fieldGroup id="fieldGroupLeft">
                            <column>
                                <field ext:index="3" id="address" property="address"/>
                            </column>
                        </fieldGroup>
                    </row>
                </rows>
            </grid>
        </groupBox>
    </layout>
</window>

Зарегистрируйте его в screens.xml с идентификатором базового экрана:

<screen id="sec$User.edit"
        template="com/sample/sales/gui/extuser/extuser-edit.xml"/>

После выполнения описанных выше действий в приложении вместо сущности User фреймворка будет использоваться ExtUser с соответствующими экранами.

Контроллер экрана может быть расширен путем создания нового класса, унаследованного от контроллера базового экрана. Имя класса указывается в атрибуте class корневого элемента расширяющего XML дескриптора, при этом выполняются обычные правила наследования XML, описанные выше.

Расширение экранов при помощи CUBA Studio

В этом примере мы расширим экран для сущности Customer из компонента Customer Management, описанного в разделе Пример создания и использования компонента: добавим кнопку Excel для таблицы браузера покупателей.

  1. Создайте новый проект в Studio и подключите к нему компонент Customer Management.

  2. Выберите New > Screen в контекстном меню элемента Generic UI в дереве проекта. Затем на вкладке Screen Templates выберите шаблон Extend an existing screen. В списке Extend Screen выберите customer-browse.xml. Новые файлы ext-customer-browse.xml и ExtCustomerBrowse.java будут созданы в модуле web.

  3. Откройте XML-дескриптор ext-customer-browse.xml и перейдите на вкладку Designer. В рабочей области будут отображены компоненты родительского экрана.

  4. Выделите таблицу customersTable и добавьте новое действие excel.

  5. Добавьте кнопку на панель buttonsPanel, связанную с действием customersTable.excel.

В итоге дескриптор экрана ext-customer-browse.xml на вкладке Text будет выглядеть следующим образом:

ext-customer-browse.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<window xmlns="http://schemas.haulmont.com/cuba/screen/window.xsd"
        messagesPack="com.company.sales2.web"
        extends="com/company/customers/web/customer/customer-browse.xml">
    <layout>
        <groupTable id="customersTable">
            <actions>
                <action id="excel" type="excel"/>
            </actions>
            <buttonsPanel id="buttonsPanel">
                <button id="excelButton" action="customersTable.excel"/>
            </buttonsPanel>
        </groupTable>
    </layout>
</window>

Рассмотрим класс контроллера экрана ExtCustomerBrowse.java.

ExtCustomerBrowse.java
@UiController("customers_Customer.browse")
@UiDescriptor("ext-customer-browse.xml")
public class ExtCustomerBrowse extends CustomerBrowse {
}

Так как идентификатор экрана customers_Customer.browse совпадает с идентификатором базового экрана, новый экран будет повсеместно вызываться взамен старого.