【问题标题】:Best way to validate ajax updates in JSF 2.0?在 JSF 2.0 中验证 ajax 更新的最佳方式是什么?
【发布时间】:2012-10-03 22:42:33
【问题描述】:

我们的团队正在编写自使用 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 强大多少。

谢谢!

【问题讨论】:

    标签: ajax validation jsf jsf-2 openfaces


    【解决方案1】:

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

    JSF 在required 属性和几个&lt;f:validateXxx&gt; 标签后面有几个内置验证器。您甚至可以通过实现Validator 接口来创建自定义验证器。

    例如检查需求:

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

    或使用the various &lt;f:validateXxx&gt; tags 之一检查它是否与模式匹配:

    <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(...));
            }
        }
    
    }
    

    &lt;f:ajax&gt; 仅用于在 HTML DOM change 事件期间提交当前输入字段(或在复选框/单选按钮的情况下为click 事件)。您不一定需要&lt;f:ajax listener&gt; 方法来通过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();
        // ...
    }
    

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

    【讨论】:

    • 那么在这种情况下,如果字段不验证,ajax 不会触发?是否有一些通用 ajaxUpdate 侦听器方法的模式来知道 bean 上的哪个字段已被修改也感谢您的回答,当我试图找到现有答案时,我已经在这里看到了你的脸,我希望你会回答!
    • 它将在更改时触发。但如果该字段未验证,则不会执行UPDATE_MODEL_VALUESINVOKE_ACTION 阶段。因此,不会调用所有操作(侦听器)。至于监听字段修改,只需使用valueChangeListener。请注意,这也不会在验证失败时被调用。 &lt;f:ajax&gt; 只是在值更改期间提交输入字段,您不一定需要 &lt;f:ajax listener&gt; ,除非您想预填充其他模型值(例如后代下拉列表)。
    • 好的,谢谢! f:ajax 和 valueChangeListener 的结合正是我所需要的!进入 valueChangeListener 方法后,我可以轻松获取 oldValue、newValue 和 getComponent().getId() 以查看更改了哪些字段!你摇滚!
    猜你喜欢
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-03
    • 2012-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多