Кастомизированная Editable Table. При потере фокуса срабатывают генераторы колонок

Добрый день. Пытаюсь реализовать кастомную редактируемую таблицу через generator ячеек:

  • первая генерируемая колонка не имеет привязки к сущности через ValueSource.
  • вторая колонка является TextField’ом и имеет эту привязку.

После ввода значения в TextField и потере фокуса отрабатывают все generator’ы на таблице (колонки которые не имеют привязки к сущности через ValueSource сбрасываются в начальное состояние).

xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<window xmlns="http://schemas.haulmont.com/cuba/screen/window.xsd"
        caption="msg://attributeValues.editor"
        focusComponent="attributeValuesTable"
        messagesPack="crm.system.web.screens.attribute">

    <data readOnly="true">
        <collection id="attributeValuesDc" class="crm.system.entities.attributes.AttributeValueVm">
            <loader id="attributeValuesDl"/>
        </collection>
    </data>

    <layout expand="attributeValuesTable" spacing="true">
        <table id="attributeValuesTable" width="100%" dataContainer="attributeValuesDc" showSelection="false" textSelectionEnabled="true">
            <columns>
                <column id="attribute.name"/>
                <column id="attribute.dataType"/>
                <column id="attribute.reference"/>
                <column id="documentValues" generator="generateDocumentValuesCell" caption="msg://attribute.documentValues"/>
                <column id="currentValue" generator="generateCurrentValueCell" caption="msg://attribute.currentValue"/>
            </columns>
        </table>
    </layout>

</window>

контроллер:

    public Component generateDocumentValuesCell(final AttributeValueVm attributeValueVm) {
        final Map<String, Integer> optionsMap = new HashMap<>();
        optionsMap.put("Test_1", 1);
        optionsMap.put("Test_2", 2);
        optionsMap.put("Test_3", 3);

        final LookupField<Integer> lookupField = this.uiComponents.create(LookupField.of(Integer.class));
        lookupField.setOptionsMap(optionsMap);
        return lookupField;
    }

    public Component generateCurrentValueCell(final AttributeValueVm attributeValueVm) {
        final InstanceContainer<AttributeValueVm> instanceContainer =
                this.attributeValuesTable.getInstanceContainer(attributeValueVm);

        final TextField<String> field = this.uiComponents.create(TextField.TYPE_STRING);
        field.setValueSource(new ContainerValueSource<>(instanceContainer, "val"));
        return field;
    }

Визуально это выглядит так:
com-video-to-gif

Т.е. при каждой смене значения любого филда в таблице заново запускаются все генераторы. Думаю это не есть ожидаемое поведение. А если из генератора вызывается затратный по ресурсам сервис? Как можно обойти этот момент? или я что-то не так делаю?

Генераторы не должны звать никаких затратных операций. Они могут вызываться по мере показа данных, в том числе при прокрутке. Более того, они сами не хранят данные и их компоненты могут быть удалены (при той же прокрутке), вам нужно сохранять их значения в объекты сущностей или поля контроллера экрана.

2 симпатии

Хорошо. Я понял.
Для текущей задачи нужна динамическая генерация филдом разных типов (текстовый, целочисленный, булевый, дата), чтобы не заводить в сущности проперти для каждого типа, думал может генерить филды без привязки к сущности. Спасибо за ответ.

Можно еще совет как получить ссылку на филд который находится в соседней колонке? Т.е. меняется значение филда одной колонки а на филде из соседней колонки к примеру вызывается setValue

Недавно отвечал на похожий вопрос вот здесь.