百分比输入和验证的Angular指令(初始验证不起作用)

时间:2015-07-23 01:34:04

标签: javascript angularjs validation angularjs-directive

我写了一个Angular指令来捕获模型中分数(100%= 1.0)中的百分比值,但是视图中的整数。它在大多数情况下都很好用,但我不知道如何触发初始验证。

例如,当向用户显示表单时,默认值为零。当min和max设置为1和100时,验证不会发生。

有人能告诉我如何让它以优雅的方式运作吗?

Plunker链接:http://plnkr.co/edit/ioraHEK63SuGMncTuHBw?p=info

export function PercentageInputFormatter() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, vm) {
            if (vm) {

                var minNumber: number = 'min' in attrs ? parseFloat(attrs.min) : Number.MIN_VALUE;
                var maxNumber: number= 'max' in attrs ? parseFloat(attrs.max) : Number.MAX_VALUE;
                var allowFraction: boolean = 'fraction' in attrs ? attrs.fraction === 'true' : false;

                vm.$parsers.push(function (value) {
                    return validatePercentage(value);
                });

                vm.$formatters.push(function (value) {
                    return XpressConvertionUtils.toPercentageDisplay(value, allowFraction ? 2 : 0);
                });

                function validatePercentage(value) {
                    if (value) {
                        var valid = !isNaN(parseFloat(value)) && isFinite(value) && parseFloat(value) >= minNumber && parseFloat(value) <= maxNumber;
                        if (!allowFraction)
                            valid = valid && value.indexOf('.') == -1;

                        vm.$setValidity('percentage', valid);
                    }

                    return valid ? value / 100 : undefined;
                }
            }
        }
    };
}

myApp.directive('dpInputFormatterPercentage', PercentageInputFormatter);

1 个答案:

答案 0 :(得分:2)

找到了一个解决方案,但请随意提出更好的方法,因为我觉得这是一种解决方法,看起来并不优雅。如果没有,希望这有助于其他人。

这部分做了诀窍:

var modelGetter = $parse(attrs.ngModel);
var initialValue = modelGetter(scope);
validatePercentage($filter('percentage')(initialValue, allowFraction ? 2 : 0));

以下完整指令代码:

    export function PercentageInputFormatter($parse, $filter) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, vm) {
            if (vm) {

                var minNumber: number = 'min' in attrs ? parseFloat(attrs.min) : Number.MIN_VALUE;
                var maxNumber: number= 'max' in attrs ? parseFloat(attrs.max) : Number.MAX_VALUE;
                var allowFraction: boolean = 'fraction' in attrs ? attrs.fraction === 'true' : false;

                var modelGetter = $parse(attrs.ngModel);
                var initialValue = modelGetter(scope);
                validatePercentage($filter('percentage')(initialValue, allowFraction ? 2 : 0));

                vm.$parsers.push(function (value) {
                    return validatePercentage(value);
                });

                vm.$formatters.push(function (value) {
                    return $filter('percentage')(value, allowFraction ? 2 : 0);
                });

                function validatePercentage(value) {
                    if (value) {
                        var valid = !isNaN(parseFloat(value)) && isFinite(value) && parseFloat(value) >= minNumber && parseFloat(value) <= maxNumber;
                        if (!allowFraction)
                            valid = valid && value.indexOf('.') == -1;

                        vm.$setValidity('percentage', valid);
                    }

                    return valid ? value / 100 : undefined;
                }
            }
        }
    };
}