I want to be able to pass a dictionary of custom validators along with possible error messages to an angular directive such that the appropriate error messages are rendered whenever the corresponding validator returns false.
我希望能够将自定义验证器的字典以及可能的错误消息传递给角度指令,以便在相应的验证器返回false时呈现相应的错误消息。
Here is some code:
这是一些代码:
base.js:
base.js:
function not_bob(value) {
return value != "bob";
}
function not_alice(value) {
return value != "alice";
}
app.js:
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:
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>
This looks complicated (and it's a contrived example), but it's mostly working; I pass an array as the argument to the directive. Each element of the array is a JSON object w/ a "name" telling me what the validator is called, a "fn" telling me what function to run to perform validation, and a "msg" telling me what to display if that function returns false.
这看起来很复杂(这是一个人为的例子),但它主要起作用;我传递一个数组作为指令的参数。数组的每个元素都是一个JSON对象,带有“name”,告诉我调用验证器是什么,“fn”告诉我运行什么函数来执行验证,还有一个“msg”告诉我如果该函数显示什么返回false。
Sure enough, the directive causes the input to be invalid when I type "bob" or "alice", and it adds the following sibling elements:
果然,当我输入“bob”或“alice”时,该指令导致输入无效,并且它添加了以下兄弟元素:
<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>
However, those elements never show up.
但是,这些元素永远不会出现。
Interestingly, if I just manually add those elements to the template (ie: not using the directive) then the correct message appears when the corresponding validator returns false.
有趣的是,如果我只是手动将这些元素添加到模板中(即:不使用该指令),那么当相应的验证器返回false时会出现正确的消息。
Any ideas on what I'm doing wrong?
关于我做错的任何想法?
Thanks
谢谢
edit: I'm pretty sure it's something to do w/ scope; Perhaps the "person_form" object in the controller isn't available in the directive?
编辑:我很确定这是做范围的事情;也许控制器中的“person_form”对象在指令中不可用?
1 个解决方案
#1
0
Aha! As suspected, the issue was w/ scope.
啊哈!如所怀疑的那样,问题是范围。
The form was in the scope of my controller and not the isolated scope of my directive. Changing the line in the directive from this:
表格在我的控制器的范围内,而不是我的指令的孤立范围。更改指令中的行:
var compiled_error_content = $compile(error_content)(scope)
to this:
对此:
var compiled_error_content = $compile(error_content)(scope.$parent)
Did the trick.
诀窍。
#1
0
Aha! As suspected, the issue was w/ scope.
啊哈!如所怀疑的那样,问题是范围。
The form was in the scope of my controller and not the isolated scope of my directive. Changing the line in the directive from this:
表格在我的控制器的范围内,而不是我的指令的孤立范围。更改指令中的行:
var compiled_error_content = $compile(error_content)(scope)
to this:
对此:
var compiled_error_content = $compile(error_content)(scope.$parent)
Did the trick.
诀窍。