Как отображать ошибки сервера в Angularjs с ng-сообщениями
У меня есть приложение angular, подтверждающее регистрационную форму. При отправке сервер также проверяет данные. Я выводил сообщения об ошибках в angular с помощью ng-сообщений.
Вот укороченная версия моей формы, которая отлично работает до сих пор.
<form name="signUpForm" novalidate data-ng-submit="attemptSignUp()">
<label for="firstName">First name</label>
<input type="email" name="email" id="email" required data-ng-model="data.user.email" />
<div class="error" data-ng-messages="signUpForm.email.$error" data-ng-show="signUpForm.$submitted" data-ng-cloak>
<p data-ng-message="required">Please provide your email</p>
</div>
</form>
Сервер проверяет, что адрес электронной почты является уникальным, а если нет, возвращает ошибку 422 (из Laravel 5) с массивом ошибок.
[
'email' => 'This email is already in use'
]
Я хотел бы объединить это и любые другие сообщения, отправленные с сервера в соответствующий блок ng-messages
. Любая идея, как я мог бы это сделать?
Ответы
Ответ 1
Простое решение состоит в том, чтобы иметь два массива. Один для клиентской стороны и один для ошибок на стороне сервера, который заполняется в вашем контроллере. Вы можете скрыть ошибки на стороне сервера, если существуют ошибки клиента или наоборот, чтобы избежать двойных сообщений.
Причина, по которой я предпочитаю иметь два массива вместо заполнения массива форм, заключается в том, что контроллер JavaScript не должен знать или быть зависимым от структуры HTML. Шаблон HTML AngularJS должен быть привязан к контроллеру, а не наоборот.
<form name="signUpForm" novalidate data-ng-submit="attemptSignUp()">
<label for="email">E-mail
<input type="email" name="email" id="email" required data-ng-model="data.user.email" />
<div class="error" data-ng-messages="signUpForm.email.$error" data-ng-show="signUpForm.$submitted" data-ng-cloak>
<p data-ng-message="required">Please provide your email</p>
</div>
<div class="error" data-ng-messages="serverErrors" data-ng-show="signUpForm.$submitted" data-ng-cloak>
<p data-ng-message="emailexists">Email already exists</p>
</div>
</label
</form>
Заметка на ярлыке: пользователи, использующие устройства чтения с экрана, не получат сообщения об ошибках, прочитанные вслух, если они не упакованы внутри метки.
Ответ 2
Ну, это не самое элегантное решение, так как вы действительно должны используйте asyncValidators в angular 1.3.x, а затем создайте специальные директивы валидации.
Ресурсы
http://plnkr.co/edit/s4jJAOqehBkFUC9osMsy?p=preview, найденный в сообщении этим guy.
Возможно здесь http://odetocode.com/blogs/scott/archive/2014/10/16/working-with-validators-and-messages-in-angularjs.aspx
И, конечно, в docs
Но будьте осторожны, поскольку это никоим образом не является полным примером, готовым к использованию. Это в основном здесь для демонстрационной цели и для того, чтобы дать вам представление о том, с чего начать. Я не беспокоился об устранении любых предыдущих ошибок, пересмотре формы или учете других ошибок проверки.
Awesomeness
Представьте, что ваш контроллер выглядит следующим образом
$scope.serverValidations = {};
$scope.attemptSignUp = function(){
Api.validateEmail($scope.email).then(angular.noop, function(data){
$scope.serverValidations = data
for(prop in $scope.serverValidations){
if($scope.signUpForm[prop]){
angular.forEach($scope.serverValidations[prop],function(validation){
$scope.signUpForm[prop].$setValidity(validation.type, false);
});
}
}
});
}
и ваши данные ответа, содержащие ошибки проверки, выглядят следующим образом
{
email:[
{type:'unique', message:'This email is already in use'}
],
name:[
{type:'maxlength', message:'Your name is to long, get a new one :)'}
]
};
Затем в вашем HTML вы можете сделать это
<div class="error" data-ng-messages="signUpForm.name.$error" data-ng-cloak="">
<p data-ng-message="required">You don't have a name?</p>
<p ng-repeat="validation in serverValidations['name']" ng-message="{{validation.type}}">{{validation.message}}</p>
</div>
Здесь грязный Codepen для вас: http://codepen.io/anon/pen/yyzMgG?editors=101
Когда вы нажимаете кнопку "Отправить", через 2 секунды (время, затрачиваемое на попадание поддельного сервера), будут представлены ваши проверки сервера.
Ответ 3
Прежде всего, вы должны установить validity
и error messages
$scope.formErrors = {};
angular.forEach(errors, function(data, name) {
if (!vm.register_form[name]) {
return;
}
$scope.formErrors[name] = data.message;
//this will set errors->server to invalid state
$scope.register_form[name].$setValidity('server', false);
});
Следующим шагом будет рендеринг ng-messages
<div ng-messages="register_form.email.$error">
<div ng-message="required">Email is required</div>
<div ng-message="email">Invalid email</div>
<div ng-message="server">{{formErrors.email}}</div>
</div>
Ответ 4
У меня был аналогичный вопрос, но решения для меня не сработали. То, что я сделал, и это/был взлом/работа, заключался в том, чтобы отправлять разные коды ошибок и устанавливать оператор case.