2

我有一个简单的请求范围实体/ pojo,它有一个枚举和一个字符串作为属性。

public Enum Type
{
    None,
    Email,
    Fax;
}

@ManagedBean(name = "testEntity")
@RequestScoped
public class TestEntity
{
    private Type type; //Default = None
    private String address;

    //getter and setter
}

该枚举有一个“电子邮件”字段,用于标识具有相关地址的电子邮件地址。
在 JSF 中,我现在想要启用/禁用与 SelectOneMenu 中当前选择的类型有关的地址 InputText 字段的验证器。

<h:form id="formId">
    <p:selectOneMenu id="type" value="#{testEntity.type}>
        <p:ajax event="change" update=":formId:address"/>
        <f:selectItem itemLabel="E-mail" itemValue="Email"/>
        <f:selectItem itemLabel="Fax" itemValue="Fax"/>
    </p:selectOneMenu>
    <p:inputText id="address" value="#{testEntity.address}">
        <f:validator validatorId="emailValidator" disabled="#{testEntity.type != 'Email'}"/>
    </p:inputText>
    <!-- button to call bean method with testEntity as param -->
</h:form>

它不起作用,验证器永远不会处于活动状态,但 ajax 调用正在工作,因为我可以在其他字段中看到更改值。

4

2 回答 2

2

不幸的是,这是不可能的。<f:xxx>标签是在视图构建期间而不是在视图渲染期间运行的标记处理程序(不是 UI 组件)。因此,如果它在构建视图期间被禁用,它将始终被禁用,直到重新创建视图(例如,通过新请求或非空导航)。

您需要有一个“全局”验证器,它根据type属性进一步委托给所需的验证器。

例如

<p:inputText ... validator="#{testEntity.validateAddress}" />

public void validateAddress(FacesContext context, UIComponent component, Object value) throws ValidatorException {
    if (type == Email) {
        context.getApplication().createValidator("emailValidator").validate(context, component, value);
    }
}

更新 OmniFaces最近添加了一个新<o:validator>标签,它应该可以解决这个问题,如下所示:

<o:validator validatorId="emailValidator" disabled="#{testEntity.type != 'Email'}"/>

在此处查看展示示例。

于 2012-05-20T23:35:00.970 回答
0

多亏了 BalusC 的帮助,也许有人对我如何解决它感兴趣。

将类型组件 clientId 传递给自定义转换器。

<f:attribute name="typeComponentId" value=":formId:type"/>

验证器:

public class TestEntity implements Validator
{
    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException
    { 
        final String typeComponentId = (String)component.getAttributes().get("typeComponentId");

        final UIInput compType = (UIInput)context.getViewRoot().findComponent(typeComponentId);

        if(compType != null)
        {
            final Type type = (Type)compType.getValue();

            if(type == Type.Email)
                new EmailValidator().validate(context, component, value);
        }
    }
}

编辑:

不能在 ui:repeat 组件(例如 p:datatable)中工作。

于 2012-05-21T22:38:28.363 回答