【问题标题】:JSF 2.0; Validator tag "disabled" depends on value from pageJSF 2.0;验证器标记“已禁用”取决于页面中的值
【发布时间】:2012-04-11 23:00:37
【问题描述】:

在我的 jsf 应用程序中,我想验证一个仅应在选中 SelectOneRadio 中的一个选项时验证的字段。

我发现<f:validator> 有一个属性,叫做“禁用”。

我可以用它来检查另一个字段的值吗?

我试过了,但我无法访问我的 bean 中的值。

<h:selectOneRadio value="#{myBean.checkedSelectOneRadioValue}">
    <f:selectItems value="#{myBean.valuesForSelectOneRadio}" />
</h:selectOneRadio>


<f:validator validatorId="myValidator" disabled="#{myBean.checkedSelectOneRadioValue == 'TEST'}" />

有没有办法在不编写自己的验证器处理程序的情况下实现这一目标?

谢谢!

【问题讨论】:

  • 您对 disabled 的检查看起来有些可疑,不应该是 #{myBean.checkedSelectOneRadioValue == 'TEST' }" 还是只是一个错字(移动大括号)?
  • 我也试过你的版本,还是不行。是不是,在验证的那一刻,来自 SelectOneRadio 的值没有存储在 bean 中?
  • 尝试在 selectOneRadio 标记中设置 partialSubmit="true",这应该包含该值。
  • myfaces 上是否存在 partialSubmit 或有替代方案?
  • 我无法使用 ajax。验证器位于另一个字段中,只有在 selectoneradio 中选择了特定值时才应对其进行验证

标签: validation jsf jsf-2


【解决方案1】:

&lt;f:validator&gt; 是标签处理程序,而不是 UI 组件。它的所有属性都是在视图构建期间评估的,而不是在视图渲染期间评估的。视图构建时间是 XHTML 文件被解析为 context.getViewRoot() 可用的 JSF 组件树的时刻。通过在 (ajax) 操作中返回 null/void,通常可以在回发到同一视图中重用相同的视图。

因此,您不能让标签处理程序属性依赖于在回发请求期间可以更改的呈现时间属性。其中一种方法是在自定义验证器本身内部执行该检查。

例如

<h:inputText>
    <f:validator validatorId="myValidator" />
    <f:attribute name="radio" value="#{myBean.checkedSelectOneRadioValue}" />
</h:inputText>

@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {     
    if (!"TEST".equals(component.getAttributes().get("radio"))) {
        return;
    }

    // Perform actual validation here.
}

您也可以改用OmniFaces &lt;o:validator&gt;。它通过基于请求的属性评估 EL 扩展了标准 &lt;f:validator&gt;

<h:inputText>
    <o:validator validatorId="myValidator" disabled="#{bean.checkedSelectOneRadioValue == 'TEST'}" />
</h:inputText>

另请参阅showcase examplesource code,相关性摘录如下:

@Override
public void apply(FaceletContext context, UIComponent parent) throws IOException {
    if (!ComponentHandler.isNew(parent)) {
        return;
    }

    final javax.faces.validator.Validator validator = createValidator(context);
    final RenderTimeAttributes attributes = collectRenderTimeAttributes(context, validator);
    final ValueExpression disabled = getValueExpression(context, "disabled", Boolean.class);
    ((EditableValueHolder) parent).addValidator(new javax.faces.validator.Validator() {

        @Override
        public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
            if (disabled == null || Boolean.FALSE.equals(disabled.getValue(context.getELContext()))) {
                attributes.invokeSetters(context.getELContext(), validator);
                validator.validate(context, component, value);
            }
        }
    });
}

【讨论】:

  • &lt;o:validator&gt; 成就了我的一天!
【解决方案2】:

使用 JSF 2.0,您可以使用 f:ajax 进行部分提交。将此标签添加到您的h:selectOneRadio

<h:selectOneRadio value="#{myBean.checkedSelectOneRadioValue}">
    <f:ajax render="idOfInputText"/>
    <f:selectItems value="#{myBean.valuesForSelectOneRadio}" />
</h:selectOneRadio>
...
<h:inputText id="idOfInputText">
    <f:validator validatorId="myValidator" 
                 disabled="#{myBean.checkedSelectOneRadioValue eq 'TEST'}" />
</h:inputText>

用验证器替换renderattribute 内容为您输入字段的真实ID。这假设 selectOneRadio 和 inputText 在同一个 NamingContainer 内。

【讨论】:

  • 我也试过这个例子,但它不起作用。现在我相信,这里发生了一些奇怪的事情:-/ 我必须对 selectoneradio 和/或 inputtext 使用绑定吗?
  • 终于,我找到了解决办法。我现在要在 myBean 中进行验证,一切都按预期工作。谢谢你的帮助!!!
【解决方案3】:

为避免在 cmets 中进行扩展讨论,我将提供我的建议作为进一步讨论的答案...

一开始应该是

disabled="#{myBean.checkedSelectOneRadioValue == 'TEST'}

disabled="#{myBean.checkedSelectOneRadioValue eq 'TEST'}

另外,至少在ICEFaces中(MyFaces也应该有这个功能),你可以使用:

<h:selectOneRadio value="#{myBean.checkedSelectOneRadioValue}" partialSubmit="true"> <f:selectItems value="#{myBean.valuesForSelectOneRadio}" /> </h:selectOneRadio>

这应该在更改 selectoneradio 的值后强制执行 ajax 请求,并且验证器禁用检查应该能够从 bean 中获取它。

如果这不起作用,MyFaces 中可能有 autoSubmit 或类似的...

【讨论】:

  • 不起作用 :-( 我尝试使用 partialSubmit、eq 和 ==,但验证器不会像我预期的那样工作。至少,我尝试将“TEST”设置为 null,并且它起作用了。选定的值不会写入 bean。我可以使用 valueChangeListener 将值存储在 bean 中吗?
  • 您在哪个组件中使用验证器?它是否有部分提交、即时或其他?新值是没有写入你的 bean 还是你的视图没有从它那里收到它?
  • 验证器在 inputText 中。是否也应该有 partialSubmit 属性?
  • partialSubmit 仅存在于&lt;ice:xxx&gt; 系列的 ICEfaces 组件中。 OP 没有以任何方式表明他/她正在使用 ICEfaces。在标准 JSF2 中,有 &lt;f:ajax&gt; 来完成这项工作。
  • 那么,你用什么? MyFaces 或标准 JSF 还是什么? , ?为什么是 而不是 ?特立尼达可能有自动提交,其他可能有类似的功能,如 ...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-18
  • 1970-01-01
  • 1970-01-01
  • 2011-04-16
  • 2015-12-19
  • 2010-12-21
  • 2012-04-01
相关资源
最近更新 更多