Подтвердить что ты не робот

Как отображать ошибки сервера в 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. Любая идея, как я мог бы это сделать?

4b9b3361

Ответ 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.