我需要创建一个验证指令,用于自动显示每个输入的所有输入错误。 此验证指令应显示当前时刻的所有错误,并且应在用户键入时自动更新错误列表。
如果输入是脏的,而不是空的并且无效,我需要显示输入的所有错误。我需要将所有错误添加到此输入元素附近的html元素中。
例如,如果输入有type =" email"和ng-minlength =" 5"和用户键入' abc'我需要在此输入附近显示此类错误:'电子邮件无效;请输入至少5个字符;'
例如,如果输入的类型为=" number" attr和min =" 200"和min-model =" minnumber"和minnumber模型设置为' 300'和用户键入' 100'我需要在此输入附近显示此类错误:'请输入最小数量500;应大于最小数量;'
如果相关模型(min-model param)更新,我还需要在prev示例中更新输入的所有错误消息。
var app = angular.module('app', []);
app.controller('appCtrl', function ($scope) {
});
app.directive('validate', function () {
return {
restrict: 'A',
require: 'ngModel', // require: '^form',
link: function (scope, element, attrs, ctrl) {
console.log('======================');
console.log(scope);
console.log(element);
console.log(attrs);
console.log(ctrl);
console.log(scope.form.$error);
angular.forEach(scope.form.$error, function (value, key) {
console.log('scope.form.$error = ' + key + ': ' + value);
console.log(value);
});
}
};
});
app.directive('positiveInteger', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue) {
var INTEGER_REGEXP = /^\d+$/;
if (INTEGER_REGEXP.test(viewValue)) { // it is valid
ctrl.$setValidity('positiveInteger', true);
return viewValue;
} else { // it is invalid, return undefined (no model update)
ctrl.$setValidity('positiveInteger', false);
return undefined;
}
});
}
};
});
app.directive('positiveFloat', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue) {
var FLOAT_REGEXP = /^(?:[1-9]\d*|0)?(?:\.\d+)?$/;
if (FLOAT_REGEXP.test(viewValue)) { // it is valid
ctrl.$setValidity('positiveInteger', true);
return viewValue;
} else { // it is invalid, return undefined (no model update)
ctrl.$setValidity('positiveInteger', false);
return undefined;
}
});
}
};
});
app.directive('minModel', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue) {
if (viewValue > scope[attrs.minModel]) { // it is valid
ctrl.$setValidity('minModel', true);
return viewValue;
} else { // it is invalid, return undefined (no model update)
ctrl.$setValidity('minModel', false);
return undefined;
}
});
}
};
});
你能帮忙制作这个验证指令吗?
或者你可以指出我正确的方向吗?
Link to JSFiddle with some code for testing
P.S。与UI-Utils类似的东西,但它们的指令不能在一个地方设置类似的错误消息。
答案 0 :(得分:13)
我想建议在这篇文章中看看这篇文章,作者正在解释如何实现你的目标,你可以深入研究代码。 link
此帖显示错误消息的示例
module = angular.module('app', []);
module.directive('showErrors', function($timeout) {
return {
restrict: 'A',
require: '^form',
link: function (scope, el, attrs, formCtrl) {
// find the text box element, which has the 'name' attribute
var inputEl = el[0].querySelector("[name]");
// convert the native text box element to an angular element
var inputNgEl = angular.element(inputEl);
// get the name on the text box
var inputName = inputNgEl.attr('name');
// only apply the has-error class after the user leaves the text box
var blurred = false;
inputNgEl.bind('blur', function() {
blurred = true;
el.toggleClass('has-error', formCtrl[inputName].$invalid);
});
scope.$watch(function() {
return formCtrl[inputName].$invalid
}, function(invalid) {
// we only want to toggle the has-error class after the blur
// event or if the control becomes valid
if (!blurred && invalid) { return }
el.toggleClass('has-error', invalid);
});
scope.$on('show-errors-check-validity', function() {
el.toggleClass('has-error', formCtrl[inputName].$invalid);
});
scope.$on('show-errors-reset', function() {
$timeout(function() {
el.removeClass('has-error');
}, 0, false);
});
}
}
});
module.controller('NewUserController', function($scope) {
$scope.save = function() {
$scope.$broadcast('show-errors-check-validity');
if ($scope.userForm.$valid) {
alert('User saved');
$scope.reset();
}
};
$scope.reset = function() {
$scope.$broadcast('show-errors-reset');
$scope.user = { name: '', email: '' };
}
});
答案 1 :(得分:11)
查看ng-messages
directive。它相当优雅。例如:
<form name="myForm">
<input type="text" ng-model="field" name="myField" required minlength="5" />
<div ng-messages="myForm.myField.$error">
<div ng-message="required">You did not enter a field</div>
<div ng-message="minlength">The value entered is too short</div>
</div>
</form>
然后,您可以将其与任何表单验证结合使用。只需将验证器的错误消息放在元素$ error对象上,它们就会自动在UI中呈现。
答案 2 :(得分:6)
这是我使用的模式(使用Angular 1.3):
app.directive('number', function() {
var NUMBER_REGEXP = /^(\d+)$/;
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$validators.number = function(modelValue, viewValue) {
return NUMBER_REGEXP.test(viewValue);
};
}
};
});
然后我能够使用这种模式检查HTML(使用Bootstrap 3.3)中的错误:
<form name="form">
<div class="form-group"
ng-class="{'has-error': form.value.$dirty && form.value.$error.number}">
<label for="id_value" class="control-label">Value:</label>
<div>
<input type="text" class="form-control" id="id_value" name="value"
ng-model="model.number" number>
<p class="help-block" ng-if="form.value.$error.number">Please enter a number</p>
</div>
</div>
</form>
说明:
number
标记中的<input name="value">
属性会触发该指令,从而导致ngModel
验证程序'number'
被调用并设置/取消设置value.$error.number
。
如果设置了value.$error.number
,则has-error
类将应用于form-group
,以便显示红色输入字段并显示帮助消息。
答案 3 :(得分:-1)
all input errors for each input automatically
就个人而言,我从那句话中看到了比专业人士更多的缺点。
如果您的下一位开发人员想要将错误消息更改为Hey, your input is too short
,该怎么办?
你想让他放弃你的一般错误信息吗?或者,在您的javascript中更改它?
如果您的下一位开发人员使用ng-show
添加自定义错误消息,该怎么办?
然后,您将有两条错误消息含义相同
那么,你不允许这样做吗?或者,您的一般指令错误消息应该隐藏?或者,将该自定义错误消息应用于一般错误消息?如果是这样,那怎么样?看,它变得复杂。
如果您对我提到的上述内容不确定,建议您不要创建常规错误消息。