Необязательные старые значения JSF возвращаются после очистки
Я использую JSF, PrimeFaces 3.2, Omnifaces 1.1, JBoss AS 7.1.1, Final, Mojarra 2.1.7
У меня есть форма, которая имеет два числовых поля, оба из которых не обязательны, например:
<h:form>
<p:inputText id="num1" value="#{bean.field1}"/>
<p:inputText id="num2" value="#{bean.field2}"/>
<p:commandButton ... ajax="true" />
</h:form>
Я также настроил OmniFaces ResetInputAjaxActionListener на лиц-конфигурации.
Свойства бина field1 и field2 являются целочисленными.
Теперь проблема в том, что если я введу, скажем, 123 для num1, введу 345 для num2 и нажму OK, все в порядке. Если я тогда удаляю 123 из num1 и помещаю abc в num2. Затем отображается ошибка проверки (преобразования), но возвращается 123!
Если я сделаю их обоих обязательными =true, тогда все хорошо.
Есть ли способ заставить это работать с дополнительными полями?
1 ответ
Это специфическая проблема Мохарры. Поле, которое привязано к Integer
неявно был преобразован IntegerConverter
который преобразует представленное пустое строковое значение в null
и устанавливает его как таковое в локальном значении компонента.
Когда форма повторно отображается после отправки, JSF сначала проверит, является ли переданное значение не нулевым, а затем отобразит его, в противном случае, если локальное значение не равно нулю, затем отобразит его, иначе отобразит значение модели. Поскольку локальное значение равно нулю, вместо этого отображается значение модели. Это действительно нежелательное поведение, о котором сообщалось несколько раз:
Это может быть исправлено переопределением UIInput#getValue()
следующее:
public Object getValue() {
return isLocalValueSet() ? getLocalValue() : super.getValue();
}
MyFaces уже делает это правильно. Я снова сообщил об этой проблеме, которая в конечном итоге перешла к спецификации 566 (обновление и, наконец, исправление в Mojarra 2.2.0 и перенесены в 2.1.21).
Между тем, самый простой способ обойти это, принимая во внимание сторонние библиотеки компонентов с их собственными средствами визуализации, такими как PrimeFaces, - это скопировать файл исходного кода javax.faces.component.UIInput
класс прямо в исходной папке вашего проекта, а затем добавить нужный UIInput#getValue()
метод. Да, неуклюжее исправление, но на самом деле нет более приятного способа, поскольку причина проблемы кроется в самом JSF API.
OmniFaces ResetInputAjaxActionListener
служит совершенно другой цели и не предназначен / не подходит для решения этой проблемы. Предполагается очистить состояние входных компонентов, для которых значение компонента не представлено, но сам компонент повторно отображается в ajax.