Пользовательская директива проверки AngularJS с динамическим черным списком - PullRequest
0 голосов
/ 25 марта 2019

Я использую пример для ngMessages из этого поста:

Как добавить пользовательскую проверку в форму AngularJS?

Работает нормально, если черный список является статическим списком элементов.

Working validation with static blacklist

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

Это директива:

.directive('blacklist', function () {
    return {
        require: 'ngModel',
        link: function (scope, elem, attr, ngModel) {
            var blacklist = attr.blacklist.split(',');
            ngModel.$parsers.unshift(function (value) {
                ngModel.$setValidity('blacklist', blacklist.indexOf(value) === -1);
                return value;
            });
        }
    };
});

Это вход, в котором используется директива:

<input type="text" id="DocumentName" name="DocumentName" class="form-control"
       ng-model="$ctrl.document.DocumentName" ng-required="true"
       blacklist="{{$ctrl.DocumentNames}}" />

В контроллере, когда в черном списке указаны статические значения, он работает как положено.

    .component('documentDetail', {
    templateUrl: '/app/document-detail/document-detail.template.html',
    controller: ['Document', 
        function DocumentDetailController(Document) {
            var self = this;
            self.DocumentNames = "Install Direct Bill Invoice,Order Preacknowledgement,Order Acknowledgement"; });

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

component('documentDetail', {
    templateUrl: '/app/document-detail/document-detail.template.html',
    controller: ['Document',  
        function DocumentDetailController(Document) {
            var self = this;
            var documentProfiles = Document.query();
            documentProfiles.$promise.then(function () {
                var bl = [];
                for (var i = 0; i < documentProfiles.length; i++) {
                    bl.push(documentProfiles[i].DocumentName);
                }
                self.DocumentNames = bl.join(',');
            });

Когда я проверяю элемент, я вижу, что данные заполнены:

Inspect Element

Но проверка действует так, как будто это пустая строка:

Validation Result

Я пытался обернуть его в $ timeout, но результат был тот же.

  component('documentDetail', {
    templateUrl: '/app/document-detail/document-detail.template.html',
    controller: ['Document', '$timeout', 
        function DocumentDetailController(Document, $timeout) {
            var self = this;
            var documentProfiles = Document.query();
            $timeout(function () {
                documentProfiles.$promise.then(function () {
                    var bl = [];
                    for (var i = 0; i < documentProfiles.length; i++) {
                        bl.push(documentProfiles[i].DocumentName);
                    }
                    self.DocumentNames = bl.join(',');
                });
            });

Как я могу получить эти значения для заполнения перед визуализацией директивы или ввода, чтобы черный список мог быть динамическим? Заранее спасибо за помощь.

1 Ответ

0 голосов
/ 25 марта 2019

Использование attr.$observe:

app.directive('blacklist', function () {
    return {
        require: 'ngModel',
        link: function (scope, elem, attrs, ngModel) {
            var blacklist = attrs.blacklist.split(',');
            attr.$observe("blacklist",function(newValue) {
                blacklist = newValue.split(',');
            });
            ngModel.$parsers.unshift(function (value) {
                ngModel.$setValidity('blacklist', blacklist.indexOf(value) === -1);
                return value;
            });
        }
    };
});

Функция наблюдателя вызывается при каждом изменении интерполированного значения.

Для получения дополнительной информации см. AngularJS attr. $ Наблюдать за API Reference


Обновление

Использование $validators API 1

Принятый ответ на ссылка на вопрос использует конвейеры $parsers и $formatters для добавления настраиваемого синхронного валидатора.AngularJS 1.3+ добавил API $validators, поэтому нет необходимости помещать валидаторы в конвейеры $parsers и $formatters:

app.directive('blacklist', function (){ 
   return {
      require: 'ngModel',
      link: function(scope, elem, attrs, ngModel) {           
          ngModel.$validators.blacklist = function(modelValue, viewValue) {
              var blacklist = attrs.blacklist.split(',');
              var value = modelValue || viewValue;
              var valid = blacklist.indexOf(value) === -1;
              return valid;
          });    
      }
   };
});

Обратите внимание, что поскольку blacklist пересчитывается каждый раз, когдаngModelController выполняет проверку, нет необходимости добавлять функцию $observe.

Для получения дополнительной информации см. Справочник по AngularJS ngModelController API - $ validators .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...