带有错误消息的自定义验证器的angularjs指令

时间:2017-10-30 19:12:23

标签: javascript jquery angularjs validation

我希望能够将自定义验证器的字典以及可能的错误消息传递给角度指令,以便在相应的验证器返回false时呈现相应的错误消息。

以下是一些代码:

base.js:

function not_bob(value) {
  return value != "bob";
}

function not_alice(value) {
  return value != "alice";
}

app.js:

(function() {
    var app = angular.module("my_app");
    app.controller("MyController", [ "$scope", function($scope) {
        var my_controller = this;
        my_controller.person = {
          "first_name": "fred",
          "last_name": "jones"
        }
        my_controller.validators = {
            "first_name" : [
                {
                    "name": "validatebob",
                    "fn": not_bob,
                    "msg": "bob is not allowed"
                },
                {
                    "name": "validatealice",
                    "fn": not_alice,
                    "msg": "alice is not allowed"
                }
            ]
        };

    }]);
    app.directive('myvalidators', ['$compile', function($compile) {
        return {
            require: ['^form', 'ngModel'],
            scope: {
                validators: '=myvalidators'
            },
            link: function(scope, elm, attrs, ctrls) {
                var form = ctrls[0];
                var ctrl = ctrls[1];
                var parent = elm.parent();
                $.each(scope.validators, function(i, validator) {
                    ctrl.$validators[validator.name] = function(modelValue, viewValue) {
                        return validator.fn(viewValue);
                    };
                    var error_class = [form.$name, ctrl.$name, "$error", validator.name].join(".");
                    var error_content = "<div ng-show='" + error_class + "'>" + validator.msg + "</div>"
                    var compiled_error_content = $compile(error_content)(scope)
                    parent.append(compiled_error_content);
                });
            }
        };
    }]);
})();

template.html:

  <html>
      <script type="text/javascript" src="base.js"></script>
      <script type="text/javascript" src="app.js"></script>
      <div ng-app="my_app">
        <div ng-controller="MyController as my_controller">
          <form name="person_form" novalidate>
            <input type="text" class="form-control" name="first_name" id="id_first_name" ng-model="my_controller.person.first_name" myvalidators="my_controller.validators['first_name']">
          </form>
        </div> 
      </div>
    </html>

这看起来很复杂(这是一个人为的例子),但它主要起作用;我传递一个数组作为指令的参数。数组的每个元素都是一个JSON对象w / a&#34; name&#34;告诉我调用验证器是什么,&#34; fn&#34;告诉我运行什么功能来执行验证,以及&#34; msg&#34;如果该函数返回false,告诉我要显示什么。

果然,当我输入&#34; bob&#34;时,该指令会导致输入无效。或者&#34; alice&#34;,它添加了以下兄弟元素:

<div ng-show="person_form.first_name.$error.validatebob">bob is not allowed</div>
<div ng-show="person_form.first_name.$error.validatealice">alice is not allowed</div>

但是,这些元素从不显示出来。

有趣的是,如果我只是手动将这些元素添加到模板中(即:不使用该指令),那么当相应的验证器返回false时会出现正确的消息。

关于我做错的任何想法?

由于

编辑:我非常确定这是一件有关范围的事情;也许&#34; person_form&#34;控制器中的对象在指令中是不可用的?

1 个答案:

答案 0 :(得分:0)

啊哈!怀疑,问题是范围。

表单属于我的控制器范围,而不是我的指令的孤立范围。更改指令中的行:

var compiled_error_content = $compile(error_content)(scope)

到此:

var compiled_error_content = $compile(error_content)(scope.$parent)

诀窍。