Совместное использование состояния проверки для нескольких полей с одним и тем же средством проверки
Я начну с того, что я искал Google и SO, и я не нашел ответа для этой конкретной ситуации. Да, есть другие посты, которые звучат одинаково, но в большей степени основаны на менталитете "MoreThan / LessThan". Это совсем не следует этому менталитету, поэтому, пожалуйста, не помечайте это как дубликат, ссылающийся на них.
Посмотрите пример Plunker
Я пытаюсь убедиться, что пользователь не вводит адрес, который уже существует в другом месте на странице. Для этого мне нужно проверить все поля адреса, так как разные места могут иметь один и тот же уличный адрес. Мне нужно, чтобы валидатор установил все связанные поля на допустимые, если какие-либо из них были недействительными после исправления адреса, чтобы не быть дубликатом. В настоящее время он только устанавливает последнее поле, измененное на действительное, а оставшееся - недействительным.
Пример Плункера демонстрирует происходящее. Я перепробовал много разных подходов, таких как итерация по всем полям и установка их на пресестин и нетронутость, а затем установка их на "грязный" и "прикосновение", чтобы снова вызывать проверки, но мне не повезло, что это сработало.
Validator
angular.directive('ruleFunc', ['$parse', function($parse) {
return {
restrict: 'A',
require: 'ngModel',
link: function($scope, $element, $attrs, $ngModel) {
var validatorName = $attrs.ruleName;
var validatorFunc = $attrs.ruleFunc;
if (!angular.isDefined(validatorName)) {
throw Error("rule-name attribute must be defined.");
}
if (!angular.isDefined(validatorFunc)) {
throw Error("rule-func attribute must be defined.");
}
// in real code I passing a function call with the model as the param
// this example demonstrated the issue I am having though
var expressionHandler = $parse(validatorFunc);
// had to use viewChangeListener because changes to the model
// were not showing up correctly in the actual implementation
$ngModel.$viewChangeListeners.push(function() {
var valid = expressionHandler($scope);
$ngModel.$setValidity(validatorName, valid);
});
});
форма
<form name="AddressForm" novalidate>
<h1>Address Form</h1>
<div style="margin:20px">
<input id="Street" type="text" name="Street" placeholder="Street" data-ng-model="ctrl.address.street" rule-func="ctrl.checkVal()" rule-name="profileHasContact"> {{!AddressForm.Street.$error.profileHasContact}}
<br />
<input id="City" type="text" name="City" placeholder="City" data-ng-model="ctrl.address.city" rule-func="ctrl.checkVal()" rule-name="profileHasContact"> {{!AddressForm.City.$error.profileHasContact}}
<br />
<input id="State" type="text" name="State" placeholder="State" data-ng-model="ctrl.address.state" rule-func="ctrl.checkVal()" rule-name="profileHasContact"> {{!AddressForm.State.$error.profileHasContact}}
<br />
<input id="Zip" type="text" name="Zip" placeholder="Zip" data-ng-model="ctrl.address.zip" rule-func="ctrl.checkVal()" rule-name="profileHasContact"> {{!AddressForm.Zip.$error.profileHasContact}}
<br />
<div ng-if="(AddressForm.Street.$error.profileHasContact
|| AddressForm.City.$error.profileHasContact
|| AddressForm.State.$error.profileHasContact
|| AddressForm.Zip.$error.profileHasContact)">Address already exists in Main Contacts</div>
<button type="submit">Submit</button>
</div>
1 ответ
Я нашел сообщение, которое было достаточно близко, чтобы я мог взломать решение. Проверка формы - Требуется один из многих в группе
Вот обновленный плункер
Обновленный валидатор
directive('ruleFunc', ['$parse', function($parse) {
return {
restrict: 'A',
require: 'ngModel',
link: function($scope, $element, $attrs, $ngModel) {
var validatorName = $attrs.ruleName;
var validatorFunc = $attrs.ruleFunc;
var groupName = $attrs.ruleGroup;
if (!angular.isDefined(validatorName)) {
throw Error("rule-name attribute must be defined.");
}
if (!angular.isDefined(validatorFunc)) {
throw Error("rule-func attribute must be defined.");
}
if(angular.isDefined(groupName)){
// setup place to store groups if needed
if (!$scope.__ruleValidationGroups) {
$scope.__ruleValidationGroups = {};
}
var groups = $scope.__ruleValidationGroups;
// setip group if needed
if(!groups[groupName]){
groups[groupName] = {};
}
var group = groups[groupName];
// assign model to group
group[$attrs.ngModel] = {
model: $ngModel
}
}
function updateValidity(valid){
if(angular.isDefined(groupName)){
// set all models in group to same validity
for(var prop in group){
if(group.hasOwnProperty(prop)){
group[prop].model.$setValidity(validatorName, valid);
}
}
}
else
{
// set this model validity if not in group
$ngModel.$setValidity(validatorName, valid);
}
}
var expressionHandler = $parse(validatorFunc);
$ngModel.$viewChangeListeners.push(function() {
var valid = expressionHandler($scope);
updateValidity(valid);
});
}
};
}]);