2015-03-30 4 views
5

Я создаю форму регистрации в Угловом с тремя входами: email, password и passwordConfirm. Мой контроллер выглядит следующим образом:

app.controller('SignupController', function ($scope, User) { 
    $scope.user = {}; 

    $scope.signup = function() { 
     User.save($scope.user, function(success) { 
      // TODO 
     }, function(error) { 
      if (error.status === 422) { 
       error.data.errors.forEach(function(item) { 
        $scope.signupForm[item.field].$setValidity(item.error, false); 
       }); 
      } 
     }); 
    }; 
}); 

Что это делает, посылая запрос на мой API, когда пользователь отправляет форму, чтобы зарегистрировать себя. Если возвращается ответ 422 (что означает ошибки проверки), я прокручиваю их и устанавливаю соответствующие входы на недопустимые данные в зависимости от возвращаемого API.

Давайте рассмотрим пример зарегистрированного адреса электронной почты. Я показываю ошибку проверки на мой взгляд, как это:

<small class="error" ng-show="signupForm.email.$error.exists">Email address taken, please use another</small> 

Это все работает отлично, но мой пользователь теперь застрял, потому что, когда они пытаются изменить адрес электронной почты на другой, справедливость email поля ISN» t, чтобы они могли повторно отправить форму (я отключу кнопку отправки на основании действительности формы).

В принципе, мне нужно свойство проверки (в данном случае exists), которое будет сброшено до true после того, как пользователь изменит модель ввода. Каков наилучший способ для меня сделать это?

Edit: Небольшой мозговолна ударил меня после публикации, я добавил это в мой контроллер:

$scope.$watch('user.email', function() { 
    // Reset exists validation property back to true 
    $scope.signupForm.email.$setValidity('exists', true); 
}); 

, который, кажется, работает. Когда пользователь изменяет значение модели после того, как вход был установлен как недействительный, он вернет его к действию. Но это не кажется мне лучшим способом сделать это. Кто-нибудь знает лучше?

ответ

0

Я также боролся с этой проблемой. После прочтения вашего поста я придумал возможное решение - создать директиву, которая наблюдает модель для изменения и сброса состояния действия по изменению (в основном то, что вы предложили, но положить в общей директивы)

angular.module('app').directive('resetValidityOnChange', function() { 
    return { 
     restrict: 'A', 
     require: 'ngModel', 
     link: function (scope, iElem, iAttrs, ngModelCtrl) { 
      ngModelCtrl.$viewChangeListeners.push(function() { 
       ngModelCtrl.$setValidity(iAttrs['resetValidityOnChange'], true); 
      }); 
     } 
    } 
} 

Вы будете должны добавить эту директиву вход ты хотел бы сбросить, например:

<input type="text" ng-model="vm.email" reset-validity-on-change="exists" /> 
0

вы подняли очень интересный вопрос. Я думаю, что с небольшим трюком вы можете сделать это без использования $ watch.

Вам понадобится небольшая директива use-form-error, которая поможет создать сложные проверки.

Пример того, как вы можете использовать его в вашем случае, см jsfiddle

angular.module('ExampleApp', ['use']) 
 
    .controller('ExampleController', function($scope) { 
 
    $scope.errorsFromAjax = null; 
 
    $scope.simulateSubmit = function() { 
 
     $scope.errorsFromAjax = { 
 
     'testVal': 'used' 
 
     }; 
 
    } 
 
    });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<script src="https://cdn.rawgit.com/Stepan-Kasyanenko/use-form-error/master/src/use-form-error.js"></script> 
 
<div ng-app="ExampleApp"> 
 
    <div ng-controller="ExampleController"> 
 
    <div ng-form="testForm"> 
 
     <label>Test value</label> 
 
     <input ng-model="testVal" name="testVal" use-form-error="{{errorsFromAjax.testVal}}" use-error-expression="errorsFromAjax.testVal && testForm.$pristine"> 
 
     <pre>errors: {{testForm.testVal.$error|json}}</pre> 
 
     <span ng-show="testForm.testVal.$error[errorsFromAjax.testVal]" class="errors">You have error!</span> 
 
     <button ng-disabled="testForm.$invalid" ng-click="simulateSubmit(); testForm.$setPristine()"> 
 
     Simulate "Submit" 
 
     </button> 
 

 
    </div> 
 
    </div> 
 
</div>

Смежные вопросы