Как передать подробности ошибки проверки для просмотра
В пользовательской директиве проверки я гарантирую, что введенное значение не конфликтует с другими в базе данных. Если это произойдет, я хотел бы сообщить пользователю не только о наличии конфликта, но и о названии элемента, с которым он конфликтует.
Хранение этих деталей в области видимости, вероятно, сработает, но мне не кажется правильным. Есть ли способ лучше?
Директива:
angular.module('myApp')
.directive('conflictcheck', function (myServer) {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue) {
var conflict = myServer.getConflict(viewValue);
if (!conflict) {
ctrl.$setValidity('conflictcheck', true);
return viewValue;
} else {
ctrl.$setValidity('conflictcheck', false);
// pass additional info regarding the conflict here
return undefined;
}
});
}
};
});
Посмотреть:
<form name="myform" action="#">
<input ng-model="foo" conflictcheck />
<div ng-if="myform.foo.$error.conflictcheck">
Error: Foo conflicts with XXXXXXXX!
</div>
</form>
1 ответ
Решение
Ошибки валидации обрабатываются FormController, поэтому разумно хранить все данные, связанные с валидацией, внутри самого объекта формы. Это можно реализовать, прикрепив произвольные данные к myform
пример:
app.factory('myServer', function(){
return {
getConflict: function(viewValue){
var comparedAgainst = 'existing@email.com';
if(viewValue === comparedAgainst){
return comparedAgainst;
}
}
}
});
app
.directive('conflictcheck', function (myServer) {
return {
require: ['ngModel', '^form'],
link: function (scope, elm, attrs, ctrls) {
var ngModelCtrl = ctrls[0];
var ngFormCtrl = ctrls[1];
ngModelCtrl.$parsers.unshift(function (viewValue) {
// getConflict returns conflicting value
var conflict = myServer.getConflict(viewValue);
if (!conflict) {
ngModelCtrl.$setValidity('conflictcheck', true);
return viewValue;
} else {
ngModelCtrl.$setValidity('conflictcheck', false);
// We attach validation-specific data to arbitrary data property
ngFormCtrl.foo.data = {
conflictcheck: conflict
};
return undefined;
}
});
}
};
});
<form name="myform" novalidate>
Email:
<input ng-model="foo" name="foo" conflictcheck />
<div ng-show="myform.foo.$error.conflictcheck">
Error: Foo conflicts with {{myform.foo.data.conflictcheck}}!
</div>
</form>