Лучший способ проверить обновления ajax в JSF 2.0?

наша команда пишет свое первое приложение JSF 2.0 с момента использования Stripes в течение многих лет, и у меня есть несколько вопросов о лучшем способе использования тега F:ajax и проверки ввода.

многие вопросы, на которые я видел ответы, имеют форму с несколькими входами, а затем кнопку отправки), но мы хотели бы поддерживать отдельные поля ввода, обновляемые сразу после изменения и сохраняемые в базе данных (без кнопки отправки. У нас это отлично работало в полосках, используя Prototype's Аякс.Запрос, но это был дополнительный шаг, которого я хотел бы избежать, если это возможно.

по сути, у нас есть страница с кучей входов на ней, непосредственно поддерживаемых бобами, например:

<h:inputText id="name" value="#{personController.name}" >
    <f:ajax listener="#{personController.ajax}" />
</h:inputText>

Как вы знаете,к моменту вызова прослушивателя значение name уже было изменено в компоненте. Это было бы удобно, но у меня есть несколько проблем с ним:

  • слушатель, очевидно, не знает, какое значение Боба было изменено
  • значение уже было изменено, я не могу выполнить проверку на стороне сервера на нем
  • Я не знаю, что такое старое значение name, даже если бы я мог выполнить какую-то проверку на нем, я бы не знал, что установить значение обратно в

прямо сейчас похоже, что нам придется реализовать какой-то посредник javascript, чтобы принять, какое свойство изменилось и новое значение, отправить это контроллеру и выполнить проверку, обновление базы данных, отправка назад чего-то для рендеринга и т. д. Но, как я уже сказал, Это то, что мы делали с полосками, и я действительно хотел бы использовать что-то более родное.

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

Я включил тег OpenFaces, потому что мы уже используем его для datatables, поэтому, если там есть что-то хорошее, мы открыт для использования. Но, насколько я могу судить, их тег o:ajax не намного мощнее, чем f:ajax JSF.

спасибо!

1 ответов


вы смотрите в неправильном направлении для достижения конкретного функционального требования проверки поля ввода. Для этого вы должны использовать обычный валидатор JSF, а не какой-то метод прослушивателя ajax, который запускается в неправильный момент (INVOKE_ACTION этап вместо PROCESS_VALIDATIONS phase) и где вы непосредственно не имеете руку на значение модели. Метод прослушивателя ajax просто должен использоваться для выполнения некоторой бизнес-логики на основе настоящее модели стоимости(ов).

в JSF имеет несколько встроенных валидаторов за и несколько <f:validateXxx> теги. Вы даже можете создать пользовательские валидаторы, реализовав Validator интерфейс.

Е. Г. проверив requireness:

<h:inputText ... required="true">
    <f:ajax />
</h:inputText>

или проверка, соответствует ли он шаблону, используя один из различные <f:validateXxx> теги:

<h:inputText ...>
    <f:validateRegex pattern="[a-z]+" />
    <f:ajax />
</h:inputText>

или с помощью пользовательского валидатора:

<h:inputText ...>
    <f:validator validatorId="myValidator" />
    <f:ajax />
</h:inputText>

С

@FacesValidator("myValidator")
public class MyValidator implements Validator {

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) {
        if (value is not valid) {
            throw new ValidatorException(new FacesMessage(...));
        }
    }

}

на <f:ajax> is просто там, чтобы представить текущее поле ввода во время HTML DOM change событие (или click событие, в случае чекбоксы/радиокнопки). Вам не обязательно нужен <f:ajax listener> метод для отправки текущего поля ввода ajax. Если вы хотите подключить событие изменения значения, просто используйте valueChangeListener.

<h:inputText ... valueChangeListener="#{bean.valueChanged}">
    <f:ajax />
</h:inputText>

С

public void valueChanged(ValueChangeEvent event) {
    Object oldValue = event.getOldValue();
    Object newValue = event.getValue();
    UIComponent component = event.getComponent();
    // ...
}

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