Угловая дистанционная форма не отображает ошибку
Я создал угловую форму, которая отображает входные ошибки проверки, полученные с сервера. Мое решение работает хорошо, за исключением одной маленькой проблемы. Если я отправляю форму без значения, после загрузки страницы я получаю правильный ответ от моего сервера, т.е. 422, но ошибка проверки не отображается. Если я затем начну вводить значение на входе, ошибка проверки мигает и исчезает.
Я почти уверен, что это как-то связано с моей директивой, но я не уверен, как это исправить. Это мой текущий код директивы:
var appServices = angular.module('webFrontendApp.directives', []);
appServices.directive('serverError', function(){
return {
restrict: 'A',
require: '?ngModel',
link: function(scope,element,attrs,ctrl){
element.on('change keyup', function(){
scope.$apply(function(){
ctrl.$setValidity('server', true);
});
});
}
};
});
Я думаю, что проблема в элементе element.on ("change keyup".... этого кода. Вот почему сообщение об ошибке мигает, когда я начинаю печатать. Также, когда я изменяю это на "change" вместо "change keyup"), сообщение об ошибке отображается постоянно, когда я начинаю печатать.
Кто-нибудь имеет представление о том, как я могу отобразить сообщение об ошибке, даже если я не вводил какое-либо значение во входные данные перед отправкой в первый раз?
ОБНОВЛЕНИЕ КАК КОММЕНТАРИЙ
Вот моя форма:
<form ng-submit="create(memberData)" name="form" novalidate>
<div class = "row form-group" ng-class = "{ 'has-error' : form.email.$dirty && form.email.$invalid }">
<input type="text" ng-model="memberData.email" placeholder="janedoe@mail.com" name="email" class="col-xs-12 form-control" server-error>
<span class="errors" ng-show="form.email.$dirty && form.email.$invalid">
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
<span ng-show="form.email.$error.server">{{errors.email}}</span>
</span>
</div>
<div class="row">
<button type="submit" class="btn btn-danger col-xs-12">Join Private Beta</button>
</div>
</form>
И мой контроллер:
$scope.memberData = {};
$scope.create = function() {
var error, success;
$scope.errors = {};
success = function() {
$scope.memberData = {};
};
error = function(result) {
angular.forEach(result.data.errors, function(errors, field) {
$scope.form[field].$setValidity('server', false);
$scope.errors[field] = errors.join(', ');
});
};
BetaMember.save({ beta_member: { email: $scope.memberData.email || "" }}).$promise.then(success, error);
};
2 ответа
Кажется, что был чрезвычайно простой обходной путь. Поскольку у меня был фильтр form.email.$ Dirty на мой взгляд, ошибка не будет отображаться, если пользователь нажал на кнопку отправить, не щелкнув сначала форму.
После удаления form.email.$ Dirty и наличия только form.email.$ Недействительным, он работает отлично. Я думаю, что в моем случае этого достаточно, так как эта проверка зависит от ответа сервера и не будет запущена до отправки формы. Объект ошибки также очищается в моем контроллере, гарантируя, что страница не загружает ошибку при первой загрузке.
Поскольку сама форма не имеет метода $setValidity, поскольку не имеет ng-модели и предполагает, что ошибка сервера не относится ни к одному полю (в этом случае предпочтителен метод $setValidity), я думаю, что самое простое решение может быть этим:
Создайте форму с некоторой случайной проверкой (для этого просто нужно указать хотя бы имя пользователя) и div, который может отображать пользовательскую ошибку сервера.
<div ng-controller="AppCtrl">
<form novalidate name="createForm">
<div class="inputWrap">
<input ng-model="name" name="name" type="text" required placeholder="John Doe">
<span ng-if="createForm.name.$dirty && createForm.name.$invalid">
Some kind of error!
</span>
</div>
<div ng-if="serverError">
{{ serverError.message }}
</div>
<input
value="Join Private Beta"
ng-disabled="createForm.$invalid || serverError"
ng-click="create()"
type="button">
</form>
</div>
Затем в вашем контроллере вы можете добавить метод create, который имеет дело с YourService (должен возвращать обещание), и если ответом будет сбой, вы можете создать простой объект с пользовательским сообщением об ошибке внутри сервера, которое также будет полезно для отключения кнопки формы, если тебе надо.
var AppCtrl = function($scope, YourService){
// Properties
// Shared Properties
// Methods
function initCtrl(){}
// Shared Methods
$scope.create = function(){
YourService.makeCall().then(function(response){
// Success!
// Reset the custom error
$scope.serverError = null;
}, function(error){
// Do your http call and then if there's an error
// create the serverError object with a message
$scope.serverError = {
message : 'Some error message'
};
})
};
// Events
// Init controller
initCtrl();
};
AppCtrl.$inject = [
'$scope',
'YourService'
];
app.controller('AppCtrl', AppCtrl);
Я имею в виду, что здесь очень простой фрагмент, я просто хотел привести пример. Ничего сложного, но вы можете масштабировать это к чему-то большему.