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

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

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

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

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

    • Если переопределяющий элемент - view, то ищется соответствующий элемент по атрибутам name, class, entity.

    • Если переопределяющий элемент - property, то ищется соответствующий элемент по атрибуту name.

    • В других случаях, если в переопределяющем элементе указан атрибут 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 в файле конфигурации Log4j:

<appender name="FILE" ...
      <param name="Threshold" value="TRACE"/>
...
<category name="com.haulmont.cuba.gui.xml.XmlInheritanceProcessor">
  <priority value="TRACE"/>
</category>

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

<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 id="address" ext:index="2"/>
          </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"/>

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

<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>
      <fieldGroup id="fieldGroup">
          <column id="fieldGroupColumn2">
              <field id="address" ext:index="4"/>
          </column>
      </fieldGroup>
  </layout>
</window>

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

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

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

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