6

自使用 Stripes 多年以来,我们的团队正在编写其第一个 JSF 2.0 应用程序,我对使用 f:ajax 标记和验证输入的最佳方式有一些疑问。

我看到回答的很多问题都有一个带有多个输入的表单,然后是一个提交按钮),但我们希望维护单个输入字段在更改后立即更新并持久保存到数据库(没有提交按钮。我们有这个工作使用 Prototype 的 Ajax.Request 在 Stripes 中很好,但如果可能的话,这是我想避免的额外步骤。

本质上,我们有一个页面,上面有一堆直接由 bean 支持的输入,例如:

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

您可能知道,在调用侦听器时,bean 上的 name 值已经更改。这会很方便,但我有一些问题:

  • 侦听器显然不知道 bean 的哪个值被更改
  • 该值已更改,我无法对其执行任何服务器端验证
  • 我不知道 name 的旧值是什么,即使我可以对其执行某种验证,我也不知道将值设置回什么

现在看起来我们必须实现某种 javascript 中间人来接收更改的属性和新值,将其发送到 Controller,并让它执行验证、更新数据库、发送回要渲染的内容等. 但就像我说的,这就是我们过去用 Stripes 做的事情,我真的很想用更原生的东西。

我确实看到,如果我们想要页面上的某种提交按钮,我们可以使用 valueChangeListener 属性之类的东西,但我也想避免大量提交。

我包含了 OpenFaces 标记,因为我们已经将它用于数据表,所以如果那里有什么好东西,我们愿意使用它。但据我所知,他们的 o:ajax 标签并不比 JSF 的 f:ajax 强大得多。

谢谢!

4

1 回答 1

11

您正在寻找错误的方向来实现验证输入字段的具体功能要求。您应该为此使用普通的 JSF 验证器,而不是在错误的时刻(INVOKE_ACTION阶段而不是PROCESS_VALIDATIONS阶段)运行并且您不直接掌握模型值的某些 ajax 侦听器方法。ajax 侦听器方法仅用于根据当前模型值执行一些业务逻辑。

requiredJSF 在属性和几个<f:validateXxx>标签后面有几个内置的验证器。您甚至可以通过实现Validator接口来创建自定义验证器。

例如检查需求:

<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>仅用于在 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();
    // ...
}

请注意,只有在特定组件上通过验证时才会调用它。

于 2012-10-03T23:38:59.663 回答