我对Jason Im的回答的改进如下:添加了两个新指令show-validation-errors和show-validation-error。
'use strict';
(function() {
function getParentFormName(element,$log) {
var parentForm = element.parents('form:first');
var parentFormName = parentForm.attr('name');
if(!parentFormName){
$log.error("Form name not specified!");
return;
}
return parentFormName;
}
angular.module('directives').directive('showValidation', function () {
return {
restrict: 'A',
require: 'form',
link: function ($scope, element) {
element.find('.form-group').each(function () {
var formGroup = $(this);
var inputs = formGroup.find('input[ng-model],textarea[ng-model],select[ng-model]');
if (inputs.length > 0) {
inputs.each(function () {
var input = $(this);
$scope.$watch(function () {
return input.hasClass('ng-invalid') && !input.hasClass('ng-pristine');
}, function (isInvalid) {
formGroup.toggleClass('has-error', isInvalid);
});
$scope.$watch(function () {
return input.hasClass('ng-valid') && !input.hasClass('ng-pristine');
}, function (isInvalid) {
formGroup.toggleClass('has-success', isInvalid);
});
});
}
});
}
};
});
angular.module('directives').directive('showValidationErrors', function ($log) {
return {
restrict: 'A',
link: function ($scope, element, attrs) {
var parentFormName = getParentFormName(element,$log);
var inputName = attrs['showValidationErrors'];
element.addClass('ng-hide');
if(!inputName){
$log.error("input name not specified!")
return;
}
$scope.$watch(function () {
return !($scope[parentFormName][inputName].$dirty && $scope[parentFormName][inputName].$invalid);
},function(noErrors){
element.toggleClass('ng-hide',noErrors);
});
}
};
});
angular.module('friport').directive('showValidationError', function ($log) {
return {
restrict: 'A',
link: function ($scope, element, attrs) {
var parentFormName = getParentFormName(element,$log);
var parentContainer = element.parents('*[show-validation-errors]:first');
var inputName = parentContainer.attr('show-validation-errors');
var type = attrs['showValidationError'];
element.addClass('ng-hide');
if(!inputName){
$log.error("Could not find parent show-validation-errors!");
return;
}
if(!type){
$log.error("Could not find validation error type!");
return;
}
$scope.$watch(function () {
return !$scope[parentFormName][inputName].$error[type];
},function(noErrors){
element.toggleClass('ng-hide',noErrors);
});
}
};
});
})();
可以将show-validation-errors添加到错误容器中,以便它将根据表单字段的有效性显示/隐藏该容器。
并且show-validation-error根据给定类型上的表单字段有效性显示或隐藏元素。
预期用途的示例:
<form role="form" name="organizationForm" novalidate show-validation>
<div class="form-group">
<label for="organizationNumber">Organization number</label>
<input type="text" class="form-control" id="organizationNumber" name="organizationNumber" required ng-pattern="/^[0-9]{3}[ ]?[0-9]{3}[ ]?[0-9]{3}$/" ng-model="organizationNumber">
<div class="help-block with-errors" show-validation-errors="organizationNumber">
<div show-validation-error="required">
Organization number is required.
</div>
<div show-validation-error="pattern">
Organization number needs to have the following format "000 000 000" or "000000000".
</div>
</div>
</div>
</form>