OmniFaces сброс двух PrimeFaces после проверки не удалось - PullRequest
3 голосов
/ 24 февраля 2020

У меня есть OmniFaces <o:validateMultiple>, установленный на два <p:selectOneMenu>. Один выпадающий список предназначен для дома, другой - для выездной команды (спортивной игры).

Валидатор проверяет, существует ли комбинация из двух команд в расписании, и если да, то Валидатор метод возвращает false. (см. таблицу выше в примере: комбинация уже существует ... один элемент в списке)

Теперь проблема:

Два поля выбора сбрасываются до их нулевых значений, но в на заднем плане они, кажется, сохраняют значение.

Пользовательский интерфейс сообщает пользователю, что «выбор был очищен», но это не то, чего ожидают я или пользователи.

Пример

До: проверка:

enter image description here

После проверки:

enter image description here

ВОПРОС :

Как я могу восстановить значения полей выбора после сбоя проверки или, скорее, как мне просто сохранить значения?

Я полагаю, что сброс входов просто JSF указанное поведение ?? 10

Это проблема с PrimeFaces (наверное, нет)?

Можно ли это сделать? Если да, то как?

PS: я не думаю, что здесь может помочь публикация кода JSF для полей выбора, но если это возможно, оставьте комментарий

1 Ответ

2 голосов
/ 25 февраля 2020

JSF должен сохранять состояние дерева компонентов, как определено жизненным циклом платформы.

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

Давайте рассмотрим ваш пример использования и сначала определим представление:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:p="http://primefaces.org/ui" xmlns:o="http://omnifaces.org/ui"
      xmlns:of="http://omnifaces.org/functions">
    <h:head>
        <title>SelectOneMenu Validation</title>
    </h:head>
    <h:body>
        <h:form>
            <o:validateMultiple id="validateMatch" components="home away"
                        validator="#{selectBackingBean.onValidateMatch}"
                        message="The combination already exists or is invalid!" />

            <p:dataList value="#{selectBackingBean.matches}" var="match">
                <f:facet name="header">Home / Away</f:facet>
                #{match.home} vs #{match.away}
            </p:dataList>
            <br/><br/>
            <p:selectOneMenu id="home" label="Please select home..." value="#{selectBackingBean.selectedHome}">
                <f:selectItems value="#{selectBackingBean.teams}" var="team" 
                           itemValue="#{team}" itemLabel="#{team}" />
            </p:selectOneMenu>
            <p:selectOneMenu id="away" label="Please select away..." value="#{selectBackingBean.selectedAway}">
                <f:selectItems value="#{selectBackingBean.teams}" var="team" 
                           itemValue="#{team}" itemLabel="#{team}" />
            </p:selectOneMenu>
            <h:panelGroup>
                <br/>
                <h:message for="validateMatch"  />
                <h:outputText value="OK!" rendered="#{facesContext.postback and not facesContext.validationFailed}" />
            </h:panelGroup>
            <br/><br/>
            <p:commandButton value="Save" action="#{selectBackingBean.onSave}" update="@form" />
        </h:form>
    </h:body>
</html>

Давайте также определим базовый компонент, содержащий представление состояние и модель:

@Data
@Named
@ViewScoped
public class SelectBackingBean implements Serializable {
    private List<String> teams;
    private List<Match> matches;

    private String selectedHome;
    private String selectedAway;

    @Data
    @AllArgsConstructor
    public class Match {
        private String home;
        private String away;
    }

    @PostConstruct
    private void init() {
        teams = Arrays.asList("Malmö FF", "GAIS", "IFK Göteborg", "AIK");
        matches = new ArrayList<>(Arrays.asList(new Match("Malmö FF", "AIK")));
    }

    public boolean onValidateMatch(FacesContext context, List<UIInput> components,
                                List<String> values) {
        return values.get(0) != values.get(1) && !matches.contains(new Match(values.get(0), values.get(1)));
    }

    public void onSave() {
        matches.add(new Match(selectedHome, selectedAway)); 
    }
}

Если мы сейчас запустим это, мы получим следующие результаты:

enter image description here

Если мы продолжим и, в конечном итоге, столкнувшись с ошибкой проверки, мы получаем следующее:

enter image description here

Обратите внимание, что он постоянно сохраняет состояние всех компонентов. В OmniFaces и JSF есть компоненты, которые позволяют вам контролировать состояние выбранных частей дерева компонентов, чтобы уйти от этого поведения.

Я предполагаю, что в вашем коде что-то происходит или вы каким-то образом сбрасывать значения базовых компонентов, связанных с компонентами.

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