用于ng-messages的Angular 1.5自定义验证指令

时间:2017-02-06 00:21:16

标签: javascript angularjs validation angularjs-directive ng-messages

我正在研究ng-messages的自定义指令,其中向输入字段添加了一个指令“custom-validation”:

 <input name="inputName" ng-model="vm.inputName" custom-validation="vm.validationConfig" class="form-control" />

并使用配置定义对象:

    vm.validationConfig = {
        "rules": [
            { "ng-minlength": 2 },
            { "ng-maxlength": 20 },
            { "ng-pattern": "/^[a-zA-Z0-9]$/" },
            "required"
        ],
        "messages": [
            { "required": "This field is required" },
            { "minlength": "Message must be over 2 characters" },
            { "maxlength": "Message must not exceed 20 characters" },
            { "pattern": "Message must contain letters or numbers only" }
        ]
    };

添加指令输入后应该简单地包装如下:

   <form name="inputName-form" ng-class="{ 'has-error':  inputName-form.inputName.$invalid }" novalidate>
        <input name="inputName" type="number" ng-model="inputName" max="100" class="form-control" required>
        <div ng-messages="inputName-form.inputName.$error" class="error-messages" role="alert"  ng-if="inputName-form.inputName.$invalid ">
            <div ng-message="number" class="message">Should be a number</div>
            <div ng-message="max" class="message">The number is too large.</div>
            <div ng-message="required" class="message">The field is required.</div>
        </div>
    </form>

到目前为止,我的指令看起来像这样:

(function () {
    "use strict";
    var module = angular.module('app');

    function isObject(obj) {
        return obj === Object(obj);
    }
    var validate = function () {
        return {
            restrict: 'A',
            replace: true,
            transclude: "element",
            scope: {
            },
            link: function (scope, element, attrs) {
                var input = attrs.name;
                //for some reason there was a space with the name
                input = input.split(' ').join('');
                scope.inputName = input;
                //create a unique form name
                scope.formName = input + "-form";
                //remove doubled form control
                element.removeClass('form-control');
                //get configuration
                scope.config = scope.$parent.vm.validationConfig;
                //object to set if form is valid or not
                scope.isValid = scope.$parent.vm.formValid;
                var formInputId = scope.formName + "." + scope.inputName;
                scope.$watch('scope.formName.$valid', function (newVal) {
                    scope.isValid[formInputId] = newVal;
                });
                var i, obj, key, val;
                scope.input = scope[attrs.name];
                //parse configuration object
                if (scope.config !== undefined) {
                    for (i = 0; i < scope.config.rules.length; i++) {
                        if (isObject(scope.config.rules[i])) {
                            obj = scope.config.rules[i];
                            key = Object.keys(obj)[0];
                            val = obj[key];
                            attrs.$set(key, val);
                        } else {
                            attrs.$set(scope.config.rules[i], true);
                        }
                    }
                    //parse messages
                    scope.msg = '';
                    for (i = 0; i < scope.config.messages.length; i++) {
                        obj = scope.config.messages[i];
                        key = Object.keys(obj)[0];
                        val = obj[key];
                        var newMessage = '<div ng-message=' + key + '>' + val + '</div>';
                        scope.msg = scope.msg.concat(newMessage);
                    }
                }
            },
            template: '<form name="{{formName}}"><div ng-transclude></div><div ng-messages="formName[inputName].$error">{{msg}}</div></form>'
        };
    };
    module.directive('customValidation', validate);
}());

此指令至少有两个问题与模板

有关
<div ng-messages="formName[inputName].$error">{{msg}}</div>
  1. 我不知道如何正确访问formName.inputName。$ error?
  2. {{msg}}将所有ng-messages显示为字符串,我之前尝试编译它但它没有用...
  3. 由于

1 个答案:

答案 0 :(得分:0)

最后我用下面的代码解决了这个问题。

(function () {
    "use strict";
    var module = angular.module('app');
    function isObject(obj) {
        return obj === Object(obj);
    }
    var validate = function ($compile) {
        return {
            restrict: 'A',
            scope: {},
            link: function (scope, element, attrs) {
                scope.formName = attrs.name + "Form";
                scope.ngMsgs = scope.formName + "." + attrs.name + ".$error";
                scope.config = scope.$parent.vm.validationConfig;
                var i, obj, key, val;
                if (scope.config !== undefined) {
                    for (i = 0; i < scope.config.rules.length; i++) {
                        if (isObject(scope.config.rules[i])) {
                            obj = scope.config.rules[i];
                            key = Object.keys(obj)[0];
                            val = obj[key];
                            attrs.$set(key, val);
                        } else {
                            attrs.$set(scope.config.rules[i], true);
                        }
                    }
                    scope.msg = '';
                    for (i = 0; i < scope.config.messages.length; i++) {
                        obj = scope.config.messages[i];
                        key = Object.keys(obj)[0];
                        val = obj[key];
                        var newMessage = '<div ng-message=' + key + '>' + val + '</div>';
                        scope.msg = scope.msg.concat(newMessage);
                    }
                }
                var wrapper = angular.element
                    (
                    '<form name=' + scope.formName + ' ng-class="{ ' + "'has-error'" + ':  ' + scope.formName + '.' + attrs.name + '.$invalid }" novalidate>'
                    );
                element.after(wrapper);
                element.removeAttr("custom-validation");
                wrapper.append(element);
                wrapper.append("<div ng-messages=" + scope.ngMsgs + " class='error-messages' role='alert' ng-if='" + scope.formName + '.' + attrs.name + ".$invalid'>" + scope.msg + "</div>");
                $compile(wrapper)(scope);
            }
        };
    };
    module.directive('customValidation', validate);
}());