Как отключить тип углов = проверка электронной почты?

Как вы могли бы отключить или, по крайней мере, изменить, как Angular проверяет ввод типа = email?

В настоящее время, если вы используете type = email, Angular, по существу, дважды проверяются. поскольку браузер (в данном случае Chrome) проверяет электронную почту, а затем Angular. Не только это, но то, что действительно в Chrome [email protected], недействительно в Angularjs.

Лучшее, что я мог найти, это ng-pattern, но ng-pattern просто добавляет 3-х шаблонную проверку для типа ввода.. вместо замены Angular проверки подлинности электронной почты. х

Любые идеи?

Ответы

Ответ 1

Примечание. Это пример для angular 1.2.0-rc.3. Вещи могут вести себя по-другому в других версиях

Как и другие, было заявлено, что немного сложно отключить проверку входных параметров по умолчанию. Вам нужно добавить свою собственную директиву в элемент ввода и обработать вещи там. Ответ Сергея правильный, однако он представляет некоторые проблемы, если вам нужно несколько валидаторов на элементе и не хотите, чтобы встроенный валидатор срабатывал.

Вот пример проверки поля электронной почты с добавленным обязательным валидатором. Я добавил комментарии к коду, чтобы объяснить, что происходит.

Элемент ввода

<input type="email" required>

Директива

angular.module('myValidations', [])

.directive('input', function () {
  var self = {
      // we use ?ngModel since not all input elements 
      // specify a model, e.g. type="submit" 
      require: '?ngModel'
      // we need to set the priority higher than the base 0, otherwise the
      // built in directive will still be applied
    , priority: 1
      // restrict this directive to elements
    , restrict: 'E'
    , link: function (scope, element, attrs, controller) {
        // as stated above, a controller may not be present
        if (controller) {

          // in this case we only want to override the email validation
          if (attrs.type === 'email') {
            // clear this elements $parsers and $formatters
            // NOTE: this will disable *ALL* previously set parsers
            //       and validators for this element. Beware!
            controller.$parsers = [];
            controller.$formatters = [];

            // this function handles the actual validation
            // see angular docs on how to write custom validators
            // http://docs.angularjs.org/guide/forms
            //
            // in this example we are not going to actually validate an email
            // properly since the regex can be damn long, so apply your own rules
            var validateEmail = function (value) {
              console.log("Validating as email", value);
              if (controller.$isEmpty(value) || /@/.test(value)) {
                controller.$setValidity('email', true);
                return value;
              } else {
                controller.$setValidity('email', false);
                return undefined;
              }
            };

            // add the validator to the $parsers and $formatters
            controller.$parsers.push(validateEmail);
            controller.$formatters.push(validateEmail);
          }
        }
      }
  };
  return self;
})

// define our required directive. It is a pretty standard
// validation directive with the exception of it priority.
// a similar approach must be take with all validation directives
// you would want to use alongside our `input` directive
.directive('required', function () {
  var self = {
      // required should always be applied to a model element
      require: 'ngModel'
    , restrict: 'A'
      // The priority needs to be higher than the `input` directive
      // above, or it will be removed when that directive is run
    , priority: 2
    , link: function (scope, element, attrs, controller) {
        var validateRequired = function (value) {
          if (value) {
            // it is valid
            controller.$setValidity('required', true);
            return value;
          } else {
            // it is invalid, return undefined (no model update)
            controller.$setValidity('required', false);
            return undefined;
          }

        };
        controller.$parsers.push(validateRequired);
      }
  };
  return self;
})
;

Там у вас есть. Теперь вы контролируете входные проверки type="email". Пожалуйста, используйте правильное регулярное выражение, чтобы проверить электронную почту, хотя.

Следует отметить, что в этом примере validateEmail выполняется до validateRequired. Если вам нужно validateRequired выполнить перед любыми другими проверками, просто добавьте его в массив $parsers (используя unshift вместо push).

Ответ 2

Очень просто. Мне пришлось изменить регулярное выражение для электронной почты, чтобы соответствовать бизнес-требованиям, поэтому я сделал эту директиву, которая настраивает регулярное выражение по электронной почте. Он по существу перезаписывает оригинальный валидатор с моим обычным. Вам не нужно возиться со всеми $parsers и $formatters (если я что-то не хватает). Поэтому моя директива была такой...

module.directive('emailPattern', function(){
    return {
        require : 'ngModel',
        link : function(scope, element, attrs, ngModel) {

            var EMAIL_REGEX = new RegExp(attrs.emailPattern, "i");

            ngModel.$validators["email"] = function (modelValue, viewValue) {
                var value = modelValue || viewValue;
                return ngModel.$isEmpty(value) || EMAIL_REGEX.test(value);
            };
        }
    }
});

Затем используйте его так, чтобы обеспечить любой шаблон электронной почты, который вы лично хотите:

<input type="email" email-pattern="[email protected]+\..+"/>

Но если вы просто хотите окончательно отключить его, тогда вы можете это сделать.

module.directive('removeNgEmailValidation', function(){
    return {
        require : 'ngModel',
        link : function(scope, element, attrs, ngModel) {
            ngModel.$validators["email"] = function () {
                return true;
            };
        }
    }
});

Затем используйте его так:

<input type="email" remove-ng-email-validation>

Ответ 3

В HTML5 вы можете использовать атрибут формы novalidate, чтобы отключить проверку браузера:

<form novalidate>
    <input type="email"/>
</form>

Если вы хотите создать собственный валидатор в angularjs, у вас есть хороший учебник и пример здесь: http://www.benlesh.com/2012/12/angular-js-custom-validation-via.html

Ответ 4

Повторяя nfiniteloop, вам не нужно связываться с $parsers или $formatters, чтобы переопределить валидаторы по умолчанию. Как указано в Angular 1.3 docs, объект $validators доступен на ngModelController. С помощью настраиваемых директив вы можете написать столько разных функций проверки электронной почты, сколько вам нужно, и называть их везде, где хотите.

Здесь один с очень хорошим стандартным регулярным выражением электронной почты из tuts: 8 регулярных выражений, которые вы должны теперь (вероятно, идентичные Angular по умолчанию, idk).

var app = angular.module('myApp', []);

app.directive('customEmailValidate', function() {
  return {
    require: 'ngModel',
    link: function(scope, elm, attrs, ctrl) {

      var EMAIL_REGEXP = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/;

      ctrl.$validators.email = function(modelValue, viewValue) {
        if (ctrl.$isEmpty(modelValue)) {
          // consider empty models to be valid
          return true;
        }

        if (EMAIL_REGEXP.test(viewValue)) {
          // it is valid
          return true;
        }

        // it is invalid
        return false;
      };
    } 
  };
});

Здесь тот, который полностью удаляет проверку:

var app = angular.module('myApp', []);

app.directive('noValidation', function() {
  return {
    require: 'ngModel',
    link: function(scope, elm, attrs, ctrl) {
      ctrl.$validators.email = function(modelValue, viewValue) {
        // everything is valid
        return true;
      };
    } 
  };
});

Использовать в вашей разметке:

<!-- '[email protected]' is valid, '@[email protected]' is invalid -->
<input type="email" custom-email-validate>

<!-- both '[email protected]' and '@[email protected]' are valid -->
<input type="email" no-validation>

Ответ 5

В моем проекте я делаю что-то вроде этого (настраиваемая директива стирает все остальные проверки, в том числе установленные angularjs):

angular.module('my-project').directive('validEmail', function() {
    return {
        require: 'ngModel',
        link: function(scope, elm, attrs, ctrl){
            var validator = function(value){
                if (value == '' || typeof value == 'undefined') {
                    ctrl.$setValidity('validEmail', true);
                } else {
                    ctrl.$setValidity('validEmail', /your-regexp-here/.test(value));
                }
                return value;
            };

            // replace all other validators!
            ctrl.$parsers = [validator];
            ctrl.$formatters = [validator];
        }
    }
});

Как его использовать (обратите внимание novalidate, для его отключения требуется проверка браузера):

<form novalidate>
    <input type="email" model="email" class="form-control" valid-email>