Почему называются валидаторы неизмененных компонентов? - PullRequest
2 голосов
/ 11 мая 2010

У меня есть форма IceFaces и несколько полей ввода.

Допустим, у меня есть это:

<ice:selectOneMenu id="accountMenu"
    value="#{accountController.account.aId}"
    validator="#{accountController.validateAccount}">
    <f:selectItems id="accountItems"
            value="#{accountController.accountItems}" />
</ice:selectOneMenu>

и это:

<ice:selectOneMenu id="costumerMenu"
    value="#{customerController.customer.cId}"
    validator="#{customerController.validateCustomer">
    <f:selectItems id="customerItems"
            value="#{customerController.customerItems}" />
</ice:selectOneMenu>

Если я изменяю одно значение, вызывается соответствующий валидатор, что нормально. Но также вызывается другой валидатор, что нехорошо, потому что пользователь получает раздражающее сообщение, чтобы вставить значение в поле, на которое он, возможно, просто собирался обратить внимание. Это все равно, что подсунуть пользователю палку «Торопись!». BAD!

Я подумал, что атрибут «absoluteSubmit» управляет этим поведением, поэтому отправляется только одна DOM-часть, на которую влияет взаимодействие с пользователем, но если я объявлю, что оба компонента были переданы частично, ничего не изменится. Тем не менее, оба валидатора вызываются, если изменяется одно значение компонента.

Как я могу предотвратить проверку всей формы до ее полной отправки?

Ответы [ 2 ]

5 голосов
/ 12 мая 2010

Когда выполняется частичная передача, полный жизненный цикл JSF все еще выполняется. Таким образом, этап проверки все еще обрабатывается, и все компоненты в иерархии компонентов проверяются.

Для этого есть веские причины. Изменение в одном компоненте может вызвать (потенциально недопустимое) изменение в другом компоненте. Например, выбор из selectOneMenu может установить значение в inputText.

ICEfaces изменяет обработку одним значительным образом: во время частичной отправки ICEfaces временно помечает все компоненты, кроме того, который вызвал sumbit, как дополнительный (required="false"). Таким образом, «требуемые» проверки пропускаются. Однако ICEfaces не отключает другие проверки.

Существует два возможных решения этой проблемы:

  1. Установите immediate="true" в дополнение к partialSubmit. Это немного меняет жизненный цикл компонента, когда выполняется частичная передача для выполнения проверки на этапе применения значений запроса. Это может привести к пропуску других проверок.

  2. Определите, произошла ли частичная отправка в вашем пользовательском валидаторе. Пропустите проверку, если это не тот компонент, который вызвал частичную отправку. К сожалению, нет документации по обнаружению частичной отправки, но я нашел решение в исходном коде для класса com.icesoft.faces.application.PartialSubmitPhaseListener.

    Оказывается, что ICEfaces добавляет два параметра запроса при выполнении частичной отправки:

    • ice.submit.partial - установите в "true", чтобы указать, что частичная отправка была сделана.
    • ice.event.captured - содержит идентификатор компонента, который сгенерировал частичную отправку.

Вы можете использовать эти два параметра в своих методах проверки. Вот пример:

public void validateAccount(FacesContext context, 
  UIComponent component, Object value) 
{
  if(!partiallySubmitted(context) || 
     componentWasPartiallySubmitted(context, component)
    // Perform validation
  }

}

public boolean partiallySubmitted(FacesContext context) {
    ExternalContext externalContext = context.getExternalContext();
    Map parameterMap = externalContext.getRequestParameterMap();   

    return "true".equals(parameterMap.get("ice.submit.partial"));
}

public boolean componentWasPartiallySubmitted(FacesContext context, 
  UIComponent component) {
    ExternalContext externalContext = context.getExternalContext();
    Map parameterMap = externalContext.getRequestParameterMap();   

    String componentId = (String) parameterMap.get("ice.event.captured");

    return component.getClientId(context).equals(componentId);
}

Конечно, прямой доступ к двум параметрам запроса, вероятно, не поддерживается. Однако до тех пор, пока группа ICEfaces не предоставит поддерживаемый способ «обнаружения» частичной отправки, это может быть единственным вариантом.

0 голосов
/ 11 мая 2010

Попробуйте выполнить проверку ajax на событии onblur (не знаю, как это сделать с помощью icefaces, но с richfaces это просто <a4j:support event="onblur" />)

...