2015-03-30 11 views
5

Tworzę formularz rejestracyjny w Angular z trzema wejściami: email, password i passwordConfirm. Mój kontroler wygląda następująco:

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); 
       }); 
      } 
     }); 
    }; 
}); 

Co to robi jest wysłanie żądania do mojego API, gdy użytkownik wysyła formularz, aby zarejestrować się. Jeśli pojawi się odpowiedź 422 (co oznacza błędy sprawdzania poprawności), wykonuję pętlę i ustawię odpowiednie dane wejściowe jako niepoprawne na podstawie zwracanego interfejsu API.

Weźmy przykład adresu e-mail już zarejestrowanego. Pokażę błędu walidacji moim zdaniem tak:

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

To wszystko działa perfekcyjnie, ale moje użytkownik jest obecnie zablokowany, ponieważ gdy próbują zmienić adres e-mail do innego, ważność ISN email pole” t zmieniono, aby umożliwić im ponowne przesłanie formularza (wyłączam przycisk przesyłania w oparciu o ważność formularza).

Zasadniczo potrzebuję, aby właściwość sprawdzania poprawności (w tym przypadku exists) została zresetowana do true po zmianie modelu wejściowego przez użytkownika. Jaki jest najlepszy sposób, aby to zrobić?

Edit: Mała fal mózgowych uderzył mnie po zaksięgowaniu dodałem to do mojego kontrolera:

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

który wydaje się działać. Kiedy użytkownik zmieni wartość modelu po tym, jak wejście zostało ustawione jako niepoprawne, przywróci to ustawienie prawidłowe. Ale nie wydaje mi się to najlepszym sposobem na zrobienie tego. Ktoś wie lepiej?

Odpowiedz

0

Mam również zmagał się z tym problemem. Po przeczytaniu postu wpadłem możliwe rozwiązanie - stworzenie dyrektywę, która ogląda model zmian i przywrócić stan ważności na zmianę (w zasadzie to, co sugeruje jednak umieścić w ogólnej dyrektywy)

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); 
      }); 
     } 
    } 
} 

Będziesz Dodaj tę dyrektywę do danych wejściowych, które chcesz zresetować, na przykład:

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

Podniosłeś bardzo interesujące pytanie. Myślę, że przy odrobinie sztuczki możesz to zrobić bez korzystania z zegarka $.

Będziesz potrzebować małej dyrektywy use-form-error, która pomaga tworzyć wyrafinowane kontrole.

Przykładem, jak można go używać w przypadku, patrz 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>

Powiązane problemy