p: список выбора теряет значения при переключении между несколькими DualListModels - PullRequest
0 голосов
/ 14 июня 2019

Я создаю веб-приложение для генерации отчетов из нескольких источников данных.Каждый источник данных имеет свой собственный набор столбцов, которые можно настроить в списке выбора Primefaces.Когда источник переключен, содержимое списка выбора должно быть обновлено, и выбранные столбцы из предыдущего источника должны быть кэшированы.

reports-edit.xhtml

<p:selectOneMenu id="select_source"
                    value="#{reportingEditView.uiReporting.source}"
                    converter="omnifaces.SelectItemsConverter"
                    required="true"
                    requiredMessage="Source selection may not be empty.">
    <f:selectItem itemLabel="Select One"
                    itemValue="#{null}"
                    itemDisabled="true"/>
    <f:selectItems
            value="#{reportingEditView.uiReporting.channel.sources}"
            var="source"
            itemLabel="#{source.name}"/>
    <p:ajax listener="#{reportingEditView.onSourceChange}"
            update="picklist_columns"/>
</p:selectOneMenu>

<p:pickList id="picklist_columns"
            value="#{reportingEditView.uiReporting.columnModel}"
            var="col"
            itemValue="#{col}"
            itemLabel="#{col.column.displayName}"
            showSourceFilter="true"
            filterMatchMode="contains"
            responsive="true"
            validator="pickListTargetNotEmptyValidator"
            immediate="true">
    <f:facet name="targetCaption">Spalten</f:facet>
    <o:converter converterId="omnifaces.ListConverter"
                    list="#{reportingEditView.uiReporting.allAvailableColumns}"/>
    <p:ajax event="transfer"
            listener="#{reportingEditView.onPicklistTransfer}"
            update="@this"/>
</p:pickList>

<p:commandButton id="button_save"
                    value="Speichern"
                    action="#{reportingView.save}"
                    icon="fa fa-fw fa-save"
                    update="panel_edit_report"
                    validateClient="true">
</p:commandButton>

ReportingEditView.java

@ManagedBean
@SessionScope
@Slf4j
public class ReportingEditView implements Serializable
{
    public void onSourceChange()
    {
        // get all available columns used by converter for new source selection.
        List<RepColumn> availableColumns =
                this.columnUtils.convertToRepColumn(this.uiReporting.getSource().getAvailableColumns());
        availableColumns.sort(new RepColumnAlphabeticalComparator());

        Source source = this.uiReporting.getSource();
        Source sourceCache = this.uiReporting.getSourceCache();

        if(!(this.uiReporting.getColumnModelCache().containsKey(source)))
        {
            this.uiReporting.getColumnModelCache().put(source, new DualListModel<>(availableColumns, new ArrayList<>()));
        }

        // cache columns for previous selected source
        this.uiReporting.getColumnModelCache().put(sourceCache, this.uiReporting.getColumnModel());

        // set columns for new source selection
        this.uiReporting.setColumnModel(this.uiReporting.getColumnModelCache().get(source));
        // set source cache for next change
        this.uiReporting.setSourceCache(source);

        this.uiReporting.setAllAvailableColumns(availableColumns);
    }

    public void onPicklistTransfer(TransferEvent event)
    {
        if(event.isRemove())
        {
            // order source columnModel alphabetically if a column is removed from reporting and therefore appears back in source column list
            List<RepColumn> orderedColumns = this.uiReporting.getColumnModelCache().get(this.uiReporting.getSource()).getSource();
            orderedColumns.sort(new RepColumnAlphabeticalComparator());
            this.uiReporting.getColumnModel().setSource(orderedColumns);
        }
    }
}

PickListTargetNotEmptyValidator.java

@FacesValidator("pickListTargetNotEmptyValidator")
public class PickListTargetNotEmptyValidator implements Validator
{
    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException
    {
        if(CollectionUtils.isEmpty(((DualListModel) value).getTarget()))
        {
            ((UIInput) component).setValid(false);
            Messages.addError(component.getClientId(context), "Column List may not be empty.", this);
        }
    }
}

Выбор столбцов, переключение между источниками и кэширование работает нормально, а значения устанавливаются так, как это должно быть при отладке.Если я первоначально выберу источник и несколько столбцов, я могу отправить форму, и отчет будет сохранен.Даже переключение с одного источника на другой и выбор некоторых столбцов работает.Но когда я теперь переключаюсь обратно на первый источник и подтверждаю, проверка завершается неудачно, потому что DualListModel, переданный в валидатор, полностью пуст.

Я использую Java 8 и Primefaces 6.2.

Что можетбыть причиной такого поведения и каковы возможные решения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...