Создание пользовательской проверки полей в angular

#angularjs #angularjs-directive #angular-directive

#angularjs #angularjs-директива #angular-директива

Вопрос:

У меня есть следующий код / plunkr и по какой-то причине form.name .$invalid всегда имеет значение true (см. Интервал сразу после поля ввода). В документации Angular мало что говорится о том, как устанавливается значение $invalid. У меня есть подозрение, что это как-то связано с имеющимся у меня javascript ctrl.$error.taken = true/false , и просто наличие объекта в объекте $error устанавливает значение $invalid в true. Может ли кто-нибудь, кто знает, как angular работает за кулисами, помочь мне?

Я хочу, чтобы ошибка «Имя должно быть буквенно-цифровым» отображалась, если имя не соответствует регулярному выражению, но я хочу, чтобы ошибка «Имя уже занято» отображалась, если имя является одним из списка. Я также указываю, какой текст «ошибка» отображать, если поле является одной из этих двух ошибок. Все эти вещи работают, за исключением того, что всегда отображается слово «ошибка». Я пытаюсь следовать стандартам angular по использованию $invalid .

Вид:

 <!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Example - example-forms-async-validation-production</title>


  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
  <script src="script.js"></script>
</head>
<body ng-app="form-example1">
  <form name="form" class="css-form" novalidate>
  <div>
    Username: 
    <input type="text" ng-model="name" name="name" username /> 
        <span ng-show="form.name.$invalid">error</span>
    <br />{{name}}<br />
    <span ng-show="form.name.$error.badContent">Name must be alpha-numeric</span>
    <span ng-show="form.name.$error.taken">Name is already taken!</span>
  </div>
</form>
</body>
</html>
  

Скрипт:

 (function(angular) {
  'use strict';
var app = angular.module('form-example1', []);

var NAME_REGEXP = /^([a-zA-Z0-9])*$/;
app.directive('username', function() {
  return {
    require: 'ngModel',
    link: function(scope, elm, attrs, ctrl) {
      var names = ['Jim', 'John', 'Jill', 'Jackie'];

      ctrl.$validators.username = function(modelValue, viewValue) {
        if (ctrl.$isEmpty(modelValue)) {
          return true; // consider empty model valid
        }

        ctrl.$error.taken = names.indexOf(modelValue) > -1;
        ctrl.$error.badContent = !NAME_REGEXP.test(modelValue);

        return !ctrl.$error.taken amp;amp; !ctrl.$error.badContent;
      };
    }
  };
});
})(window.angular);
  

Plunkr:
https://plnkr.co/edit/LBRR14PpjAQigafOVTgQ?p=preview

Ответ №1:

  1. Используйте отдельные директивы, одну для проверки буквенно-цифровой, а другую для имени пользователя, которое уже заняло проблему.
  2. $ctrl.validators.alphaNumeric предоставляет $error.alphaNumeric в FormController. Вам не нужно манипулировать значением в файле $error.xxx, оно устанавливается автоматически на основе возвращаемого значения валидатора.
  3. Пожалуйста, проверьте plunkr.
  4. Также см. https://code.angularjs.org/1.5.8/docs/api/ng/type/ngModel .ngModelController Хотя я и не проверял это, но я считаю, что теперь у вас должен быть класс ошибок ng-invalid-alpha-numeric из-за того, что теперь установлена форма.$error.alphaNumeric .

JS

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

app.controller('MainCtrl', function($scope) {
  $scope.model = {};
});

app.directive('validateAlphaNumeric', function () {

  var REGEX = /^([a-zA-Z0-9])*$/;

  return {
    require: 'ngModel',
    link: function (scope, element, attrs, ctrl) {

      ctrl.$validators.alphaNumeric = function (modelValue, viewValue) {

    if (REGEX.test(viewValue)) {
      return true
    }
    return false;
      };

    }
  };
});

app.directive('validateUserNotTaken', function () {

  return {
    require: 'ngModel',
    link: function (scope, element, attrs, ctrl) {
      var names = ['Jim', 'John', 'Jill', 'Jackie'];
      ctrl.$validators.userNotTaken = function (modelValue, viewValue) {

    if (names.indexOf(modelValue) == -1) {
      return true
    }
    return false;
      };

    }
  };
});
  

HTML

 <body ng-controller="MainCtrl">
    <form name="myForm">
      <input type="text" validate-alpha-numeric validate-user-not-taken ng-model="model.value1">
      <p ng-if="myForm.$error.alphaNumeric">Should be alphanumeric</p>
      <p ng-if="myForm.$error.userNotTaken">User Exists!</p>
      <p ng-if="myForm.$error.alphaNumeric || myForm.$error.userNotTaken">Error</p>
     </form>
  </body>
  

Рабочий plunkr: https://plnkr.co/edit/MZ7DMW?p=preview

Комментарии:

1. можете ли вы добавить обе функции проверки в одну и ту же директиву?

2. Эти валидаторы были именно тем, что я искал! Вам разрешено иметь более одного средства проверки в одной директиве.