如何控制Angular验证器的评估顺序?

时间:2017-02-15 16:44:02

标签: javascript angularjs typescript

使用Angular 1.5

我理解,当指令被触发时,角度验证器会被添加到字段中,然后当控件的值更改所有验证器时。我有3个不同的金额字段验证(正确的字符,最大长度,不能为零)。如果字段不是有效金额,我不需要评估为不能为零,而是我第二次检查control.$validator.amountFormat.

而不是经过所有有效金额检查

无论如何都要保证我构建的格式验证器将在大于零的验证器之前发生。我还有很多其他场景。

这就是我所拥有的:

ctrl.$validators.amountFormat = (modelValue: string, viewValue: string) => {
    if (ctrl.$isEmpty(viewValue)) {
        return true;
    }

    return isAmount(viewValue);
}

ctrl.$validators.amountGreaterThanZero = (modelValue: string, viewValue: string) => {
    if (!isAmount(viewValue)) {  //isAmount() is the function used to determine format
        return true;
    }

    return parseFloat(viewValue) > 0;
}

这就是我想要的:

ctrl.$validators.amountGreaterThanZero = (modelValue: string, viewValue: string) => {
    if (ctrl.$error.amountFormat) {
        return true;
    }

    return parseFloat(viewValue) > 0;
}

1 个答案:

答案 0 :(得分:2)

以下链接说明$ parsers成功完成后$ validators将触发。在Meet the $validators pipeline部分:

https://blog.thoughtram.io/angularjs/2015/01/11/exploring-angular-1.3-validators-pipeline.html

因此,不要试图让验证者在彼此之前解雇。我能够编写一个解析器(简单地说)如果用户输入有效金额,将其存储在modelValue中,否则将modelValue留空。

ctrl.$parsers.push((viewValue: string) => {
    var modelReturnValue = '';

    if (ctrl.$isEmpty(viewValue)) { return modelReturnValue; }

    if (this.isAmount(viewValue)) {
        modelReturnValue = viewValue;
    }

    return modelReturnValue;
});

然后在我的验证器中,而不是使用viewValue,我可以使用modelValue

ctrl.$validators.amountFormat = (modelValue: string, viewValue: string) => {
    if (ctrl.$isEmpty(viewValue)) {
        return true;
    }

    //format validator still has to check the viewValue because if the user doesnt type anything in we do not want to show a format error
    return isAmount(viewValue);
}

可选地,amountFormat验证器可以简单地检查是否viewValue != modelValue,因为如果viewValue是有效金额,我们只是将其存储为modelValue。

ctrl.$validators.amountGreaterThanZero = (modelValue: string) => {
    //Because we are returning an empty string if the value is not a valid amount, we can comfortably say that the modelValue will be empty
    if (ctrl.$isEmpty(modelValue)) {  
        return true;
    }

    return parseFloat(modelValue) > 0;
}