angular custom validation unique email trigger once

ぐ巨炮叔叔 提交于 2020-01-05 03:35:18

问题


I'm having a lot of troubles and I don't understand the behavior of

custom validation or may be I misunderstand something.

The directive trigger once ousite watch and inside invalid and twice inside watch (at least in my test)

My goal would be trigger the extra custom validation after the required

and email rules are valid but it doesn't work at all.

So the code

<!doctype html>
<html data-ng-app="myApp">
    <head>
         <meta charset="utf-8">

    </head>
    <body>
        <div data-ng-controller="myCtrl">
            <form novalidate id="frm-signup" name="addContestantFrm" data-ng-submit="addContestant()">
                <div>
                    <label for="email">Email: *</label>
                    <input type="email" id="email" name="email" class="input-medium" tabindex="3" title="email" maxlength="255" value="{{contestant.email}}" placeholder="email" data-ng-model="contestant.email" required email-unique />
                </div>
                <div>
                    <input type="submit" id="sbmt" name="sbmt" class="input-sbt" data-ng-disabled="!addContestantFrm.$valid" value="Send" />
                </div>
            </form>
        </div>
         <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
        <script src="http://code.angularjs.org/1.0.8/angular.min.js"></script>
        <script>
            var app = angular.module('myApp', []);
            app.factory('Contestant',function($http){
                return {
                    checkUniqueEmail : function(email){
                        return $http.post('./checkemail.php',{email:email});
                    }
                }
            });
            app.controller('myCtrl',function($scope){

            });
            app.directive('emailUnique',function(Contestant) {
                return {
                    require: 'ngModel',
                    link: function(scope, element, attrs,ctrl) {
                    Contestant.checkUniqueEmail(attrs.emailUnique).success(function (response) {
                    ctrl.$setValidity('emailUnique', true);
                    console.log('inside valid');
                    console.log(attrs.emailUnique);
                    console.log('end inside valid');
                    return attrs.emailUnique;
                })
                .error(function (data) {
                    console.log('inside invalid');
                    ctrl.$setValidity('emailUnique', false);
                     console.log('end inside invalid');
                    return undefined;
                });

               scope.$watch(attrs.ngModel, function() {
                    console.log('I am inside watch');
                    console.log(ctrl.$error.required);
                    console.log(ctrl.$error.email);
                    console.log('end watch');

                });
                console.log('ouside');
                console.log(attrs.emailUnique);
                console.log('end ouside');

            }
        }
    });
        </script>
    </body>
</html>

and the fake check

<?php
$data = file_get_contents("php://input"); 
$data = json_decode($data,true);
if(isset($data['email'])){
    if(empty($data['email'])){
        header("HTTP/1.0 404 Not Found");
        exit;
    }
    elseif($data['email'] !== 'admin@goo.com'){
        header("HTTP/1.0 404 Not Found");
        exit;
    }
    else{
        header("HTTP/1.1 200 OK");
        return $data['email'];
        exit;
    }
}

回答1:


app.directive('emailUnique',function(Contestant) {
                return {
                    require: 'ngModel',
                    link: function(scope, element, attrs,ctrl) {
                        ctrl.$parsers.unshift(function(viewValue) {
                            console.log(ctrl.$error.email);
                            Contestant.checkUniqueEmail(viewValue).success(function (response) {
                                ctrl.$setValidity('emailUnique', true);
                                console.log(viewValue);
                                return viewValue;
                            })
                            .error(function (data) {
                                ctrl.$setValidity('emailUnique', false);
                                console.log(viewValue);
                                return undefined;
                            });
                        });
                    }
                }
            });

Now it works but I'd like call the xhr only when there is a valid email ctrl.$error.email give me always false :(




回答2:


From AngularJS documentation:

$parsers: Array of functions to execute, as a pipeline, whenever the control reads value from the DOM. Each function is called, in turn, passing the value through to the next. The last return value is used to populate the model. Used to sanitize / convert the value as well as validation. For validation, the parsers should update the validity state using $setValidity(), and return undefined for invalid values.

Based on this, if we add the $parser at the end of the pipe (using ctrl.$parsers.push) then, if the input value is invalid, viewValue parameter will be undefined.

I wrote this example to clarify how parsers works: http://jsfiddle.net/oua78v19/7/ (check console to see how parameter value is changed when it is valid)

Updated code sample:

app.directive('emailUnique',function(Contestant) {
                return {
                    require: 'ngModel',
                    link: function(scope, element, attrs,ctrl) {
                        ctrl.$parsers.push(function(viewValue) {
                            if (viewValue) {
                                // we have a valid email address
                                // we can do now an ajax call to see 
                                // if email is already in use
                            }
                        });
                    }
                }


来源:https://stackoverflow.com/questions/19015292/angular-custom-validation-unique-email-trigger-once

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!