2016-08-05 16 views
0

TLDR: Warum empfängt Winkel ngMinlength $ beobachten Updates mit interpolierten Werten, aber meine benutzerdefinierte Validierung Richtlinie nicht?

Link to plnkr

Ich arbeite an einer benutzerdefinierten Überprüfungsrichtlinie in Angular 1.3 und haben etwas bemerkt, das im Widerspruch zu sein scheint. Die eckige Anweisung scheint interpolierte Aktualisierungen von attr. $ Observe zu erhalten, aber die von mir erstellte Anweisung verhält sich nicht auf die gleiche Weise.

Ich kann $ watch verwenden, um es zu beheben, oder binde einen interpolierten Wert, aber stimmt nicht mit den vorhandenen Validierungsdirektiven überein. Was ist der Unterschied, und wie kann ich meine benutzerdefinierte Anweisung ähnlich wie die integrierten Validierungsanweisungen arbeiten lassen?

Angular der Richtlinie

var minlengthDirective = function() { 
     return { 
      restrict: 'A', 
      require: '?ngModel', 
      link: function(scope, elm, attr, ctrl) { 
      if (!ctrl) return; 

      var minlength = 0; 
      attr.$observe('minlength', function(value) { 
       minlength = int(value) || 0; 
       ctrl.$validate(); 
      }); 
      ctrl.$validators.minlength = function(modelValue, viewValue) { 
       return ctrl.$isEmpty(viewValue) || viewValue.length >= minlength; 
      }; 
      } 
     }; 
     }; 

Meine Richtlinie

function observeMinLength($log){ 
    return { 
     restrict: 'A', 
     require: '?ngModel', 
     link: function (scope, elm, attr, ctrl) { 
      if (!ctrl) return; 

      var min; 

      //Problem 1: observered value is not interpolated 
      //Problem 2: observe is only fired one time 
      attr.$observe('observeMinlength', function (value) { 
       $log.debug('observed value: ' + value); 
       min = parseInt(value, 10) || 0; 
       ctrl.$validate(); 
      }); 

      ctrl.$validators.mymin = function (modelValue, viewValue) { 
      var len = 0; 
      if (viewValue){ 
       len = viewValue.length; 
      } 
      return ctrl.$isEmpty(viewValue) || viewValue.length >= min; 
      }; 
     } 
    }; 
} 

Antwort

0

Beachten Sie, dass die ngMinlength Direktive $ Beobachtung des "minlength" Attribut ist, nicht das "ngMinlength" Attribut. Ich glaube, das Problem ist, dass die Input-Direktive von Angular das minlength-Attribut basierend auf dem interpolierten Wert setzt ... also während sich das ngMinlength-Attribut nicht ändert, während sich sein Wert ändert, ist das minlength-Attribut beobachtbar. In Ihrer Anweisung ändert sich das Attribut "observeMinLength" nicht, aber der Wert der scope-Eigenschaft, die Sie übergeben, funktioniert.

Wenn Sie in den eckigen Quellcode schauen: https://github.com/angular/angular.js/blob/13b7bf0bb5262400a06de6419312fe3010f79cb2/src/ng/directive/attrs.js#L379 können Sie sehen, dass angular die Scope-Variable überwacht und die Attributvariable für alle Attribute in der ALIASED_ATTR-Auflistung festlegt. Dass die Sammlung als

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

in https://github.com/angular/angular.js/blob/2e0e77ee80236a841085a599c800bd2c9695475e/src/jqLite.js#L575

Also kurz gesagt definiert ist, hat Angular Sonderbehandlung für eigenes Attribut basierter Validierung Richtlinien. Sie müssen also Ihre Bereichseigenschaft überwachen, anstatt das Attribut zu beobachten.

+0

Danke! Das scheint dann die ganze Geschichte zu sein. Die Dokumentation für $ object schien zu implizieren, dass sie den Wert interpolieren würde, und ich nahm an, dass das fehlende Präfix von der Normalisierung des Attributnamens herrührte. Ich hätte nie gedacht, die jqLite-Datei zu betrachten! –