2016-01-05 2 views
0

Я написал директиву multiple-pattern проверки, которая принимает несколько проверки регулярных выражений:.

link: function (scope, elm, attr, ctrl) { 
    if (!ctrl) return; 

    let validators = []; 
    attr.$observe('multiplePattern', function (patterns) { 
     // doesn't get there after value change 
     var parsed = scope.$eval(patterns); 

, но я не понимаю, почему $observe обратного вызова не срабатывает, когда переменная на контроллере validationRegexps изменяется (обратный вызов нг повтора в срабатывает, когда regexp переменная изменена):

$scope.regexp = '^\\S*$'; 
$scope.validationRegexps = {'nospaces': '^\\S*$', 'nofirstnumber': '^[A-Za-z]'}; 

setTimeout(function() { 
    $scope.$apply(function() { 
     $scope.regexp = '[^abc]'; 
     $scope.validationRegexps = {'noabc': '[^abc]'}; 
    }) 
}, 5000); 

Использование:

<div ng-pattern="regexp" multiple-pattern="validationRegexps"></div> 
+1

Почему вы не используете 'scope: {multiplePatterns: '='}'? –

+0

в двух словах: attrs - строка, вы наблюдаете строковые изменения, вы передаете строку _validationRegexps_, эта строка не изменяется, поэтому обратный вызов не запускается – Grundy

+0

@ DanielA.White, потому что моя директива не создает изолированную область. –

ответ

1

$observe действительно работает так же, как и $watch. Но разница между этими двумя составляет $watch принимает значение string или expression & оценивает каждый цикл дайджеста, где $observe принимает interpolated выражение, подобное {{validationRegexps}}.

attr.$observe будет работать только тогда, когда вы использовали attribute с интерполированным контентом {{}}.

HTML

<div ng-pattern="regexp" multiple-pattern="{{validationRegexps}}"></div> 
+0

спасибо, но почему тогда мне не нужно использовать интерполированное выражение для 'ng-pattern' для срабатывания обратного вызова? –

+0

@Maximus, если вы отлаживаете директивный код 'ng-pattern', вы узнаете об этом. Я буду запускать функцию обратного вызова '$ observ' один раз. на начальном, который будет принимать значение из переменной «scope» и будет помещен в значение переменной «regx», которое затем будет использоваться ['ctrl. $ validators.pattern'] (https://github.com/angular/angular. js/blob/master/src/ng/директива/validators.js # L169) –

+0

Да, я только что сделал именно это, пожалуйста, см. мой ответ. –

0

Я только что проверил исходный код, и кажется, что есть специальная обработка ng-pattern значение, которое позволяет корректную работу $observe без указания интерполяции:

var ALIASED_ATTR = { 
    'ngMinlength': 'minlength', 
    'ngMaxlength': 'maxlength', 
    'ngMin': 'min', 
    'ngMax': 'max', 
    'ngPattern': 'pattern' 
}; 


forEach(ALIASED_ATTR, function(htmlAttr, ngAttr) { 
    ngAttributeAliasDirectives[ngAttr] = function() { 
    return { 
     priority: 100, 
     link: function(scope, element, attr) { 
     //special case ngPattern when a literal regular expression value 
     //is used as the expression (this way we don't have to watch anything). 
     if (ngAttr === "ngPattern" && attr.ngPattern.charAt(0) == "/") { 
      var match = attr.ngPattern.match(REGEX_STRING_REGEXP); 
      if (match) { 
      attr.$set("ngPattern", new RegExp(match[1], match[2])); 
      return; 
      } 
     } 

     scope.$watch(attr[ngAttr], function ngAttrAliasWatchAction(value) { 
      // here the value is already interpolated 
      attr.$set(ngAttr, value); 
     }); 
     } 
    }; 
    }; 
}); 

В отличие не интерполированное значение для других случаев использования $observe:

$observe: function(key, fn) { 
    var attrs = this, 
     $$observers = (attrs.$$observers || (attrs.$$observers = createMap())), 
     listeners = ($$observers[key] || ($$observers[key] = [])); 

    listeners.push(fn); 
    $rootScope.$evalAsync(function() { 
     if (!listeners.$$inter && attrs.hasOwnProperty(key) && !isUndefined(attrs[key])) { 
     // not interpolated value is passed down here 
     fn(attrs[key]); 
     } 
    }); 

    return function() { 
     arrayRemove(listeners, fn); 
    }; 
    } 
+0

Я бы не предлагал вам редактировать код API .. какой код исправить вашу проблему, но это может привести к другим последствиям. –

+0

Я не редактирую это, я просто перечислил его здесь, чтобы показать, почему '$ observer' работает по-разному для' ng-repeat' и моей настраиваемой директивы –

Смежные вопросы