2016-10-10 5 views
5

Я использую валидатор OmniFaces' <o:validateAll> для проверки количества входных компонентов. Это прекрасно работает, пока я не помещаю его в RichFaces <rich:tabPanel>. Когда я делаю это и оставляю поля пустыми, проверка не выполняется (как и ожидалось), но активная вкладка изменяется независимо от неудачной проверки. Другие валидаторы, которые я пытался предотвратить, отключили tabPanel от переключения на другую вкладку, всякий раз, когда проверка не выполняется.Почему <o: validateAll> ведет себя иначе, чем другие валидаторы?

В чем причина этого?

В настоящее время я использую OmniFaces 2.1 и RichFaces 4.5.17.Final с Mojarra 2.2.12 на Wildfly 9.0.2.

Вот XHTML-код, чтобы воспроизвести проблему:

<ui:composition xmlns:ui="http://xmlns.jcp.org/jsf/facelets" 
       xmlns:f="http://xmlns.jcp.org/jsf/core" 
       xmlns:h="http://xmlns.jcp.org/jsf/html" 
       xmlns:o="http://omnifaces.org/ui" 
       xmlns:rich="http://richfaces.org/rich"> 

    <h:form id="form"> 

     <rich:messages /> 

     <rich:tabPanel id="tabPanel"> 

     <rich:tab id="tab1" header="Tab 1"> 
      <h:inputText id="myDouble" value="#{someDoubleVal}"> 
      <f:validateDoubleRange minimum="1.0" maximum="2.0"/> 
      </h:inputText> 
      <o:validateAll id="allValid" components="myDouble" message="Missing value!" /> 
     </rich:tab> 

     <rich:tab id="tab2" header="Tab 2"> 
      Just another tab to switch. 
     </rich:tab> 

     </rich:tabPanel> 

    </h:form> 

</ui:composition> 

Введите значение вне 1.0 и 2.0 и попробуйте переключиться на вкладку 2, чтобы увидеть ожидаемое поведение, вызванное <f:validateDoubleRange>: отображается лицо-сообщение и первая вкладка все еще активна.

Оставьте поле пустым и попробуйте переключиться на вкладку 2, чтобы увидеть поведение <o:validateAll>: проверка достоверности не отображается (отображается сообщение лиц), но активирована вкладка 2.

Обновление: Описанное поведение применяется с switchType="ajax" (по умолчанию), а также с switchType="server". В обоих случаях вкладка выполняет подачу включенных входов, поэтому с точки зрения пользователей переключатель табуляции, похоже, совпадает с <h:commandButton> submit (технически могут быть различия, я не знаю, детали реализации вкладки).

Если я выполнить вкладки-переключатель с помощью обычной <h:commandButton> с <f:setPropertyActionListener>, то <o:validateAll> ведет себя так же, как и другие валидаторы, то есть язычок-переключатель не выполняется из-за ошибки проверки.

<rich:tabPanel id="tabPanel" activeItem="#{bb.activeTab}"> 
... 
    <rich:tab id="tab1" name="tab1" header="Tab 1"> 
    ... 
    <h:commandButton value="submit"> 
     <f:setPropertyActionListener value="tab2" target="#{bb.activeTab}" /> 
    </h:commandButton> 
    ... 
    </rich:tab> 
</rich:tabPanel> 

Примечание: Это просто минималистичный пример, показывающий поведение проблематичным. В моем реальном коде у меня есть не только один компонент, проверенный на <o:validateAll>, и я действительно связываю входные значения с бэкэндом. Наблюдаемое поведение точно такое же.

+0

Я только что понял, изменив положение тега '' в коде XHTML, изменит поведение! Поместите его перед компонентами, которые должны быть фактически проверены, и работает так, как ожидалось. Это желаемое поведение или ошибка в OmniFaces? В документации не упоминается этот эффект. Есть идеи? –

+0

Не знаете, как богатые: tabPanel работает под обложками, но поведение упорядоченности описано в первом абзаце «общего использования» http://omnifaces.org/docs/javadoc/2.5/org/omnifaces/component/validator/ValidateMultipleFields. html – BalusC

+0

Правильно, порядок заказа документирован. Но в нем также говорится: «Этот валидатор можно поместить в любом месте формы, но имейте в виду, что компоненты будут проверяться в порядке, как они появляются в форме.». Однако это не объясняет, почему валидация вызывает различное поведение внешней вкладки. Но, возможно, это особенность компонента RichFaces. У меня сложилось впечатление, что у RichFaces больше таких странностей. Может быть, я попробую пример с PrimeFaces и посмотрю, как это работает. –

ответ

2

проблема 2 раза.

Первая проблема, <o:validateAll> не явно вызвать context.renderResponse(), когда проверка не удалась, и оставляет эту работу JSF, который будет неявно называть его во время фазы Validations, когда по меньшей мере один компонент ввода признан недействительным после <o:validateAll> закончилась, или иным образом в течение последующая фаза значений модели обновления.

Вторая проблема: <rich:tabPanel> Событие переключения табуляции ставится в очередь для фазы значений модели обновления, а не для фазы приложения-приложения. Я не уверен, почему ребята из RichFaces спроектировали его так, но следствие заключается в том, что событие переключателя табуляции запускается в любом случае, даже если проверка достоверности не удалась во время фазы значений модели обновления.

При перемещении <o:validateAll> прежде, чем по меньшей мере одного связанного входного компонента, то JSF будет неявно называть context.renderResponse() во время фазы Validations уже и, следовательно, полностью пропустить фазу значений модели обновления и поэтому очередь <rich:tabPanel> вкладка переключатель событие не будет иметь шанс быть вызывается.

Я установил его в OmniFaces 2.6-SNAPSHOT согласно issue 322. При использовании OmniFaces 2.6 или новее больше не должно иметь значения, где <o:validateAll> помещается в дерево, чтобы добиться желаемого поведения события табуляции <rich:tabPanel>, чтобы не вызываться.

+0

Спасибо за подробный ответ и спасибо за исправление в OmniFaces. –

+0

Спасибо, что задали этот вопрос. – BalusC

 Смежные вопросы

  • Нет связанных вопросов^_^