2013-07-12 17 views
15

Geçmişte olması için tarih gerektiren bir özel doğrulayıcı oluşturdum. Doğrulama, alana manuel olarak girerken harika çalışır gibi görünüyor. Bununla birlikte, eğer programlı olarak tarihi değiştirirseniz (modeli yazımın tersine doğrudan model olarak değiştirin), doğrulama yanmaz.AngularJS özel doğrulama, programlı olarak değiştirilirken tetiklenmiyor

Belgede belirtildiği gibi özel doğrulama yönergesini yapıyorum. Problemi gösteren Here is a jsFiddle. Kemanda, "Tarihi programlı olarak değiştir" düğmesini tıklatırsanız, doğrulama hatasının görüntülenmediğini görebilirsiniz (ancak bunu el ile değiştirirseniz).

myApp.directive('pastDate', function() { 
    return { 
     restrict: 'A', 
     require: '?ngModel', 
     link: function (scope, element, attrs, ctrl) { 
      ctrl.$parsers.unshift(function (viewValue) { 
       var today = new Date(); 
       today = new Date(today.getFullYear(), today.getMonth(), today.getDate()); 

       if (new Date(viewValue) < today) { 
        ctrl.$setValidity('pastDate', true); 
        return viewValue; 
       } 
       ctrl.$setValidity('pastDate', false); 
       return undefined; 
      }); 
     } 
    }; 
}); 

cevap

18

, $parsers kontrolleri görünüm-to-model yönünün boru hattı bağlama modelinin iki yolu ve $formatters kontrolleri model için boru hattı vardır: İşte (aynı zamanda keman olarak) direktifi kodudur görüş açısı. Denetleyicideki modeli güncelleştirdiğinizde, değişiklik $formatters boru hattından geçer.

Kodunuzu şu adresten güncelleştirdim: this, bu nedenle her iki şekilde de işler.

myApp.directive('pastDate', function() { 
    return { 
     restrict: 'A', 
     require: '?ngModel', 
     link: function (scope, element, attrs, ctrl) { 
      function validate (value) { 
       var today = new Date(); 
       today = new Date(today.getFullYear(), today.getMonth(), today.getDate()); 

       if (new Date(value) < today) { 
        ctrl.$setValidity('pastDate', true); 
        return value; 
       } 
       ctrl.$setValidity('pastDate', false); 
       return value; 
      } 
      ctrl.$parsers.unshift(validate); 
      ctrl.$formatters.unshift(validate) 
     } 
    }; 
}); 
+0

Felix :) – Terry

+1

@Terry yah maalesef ofiste kek özleyeceğiz bugün bu beni yendi. – yuxhuang

+0

Açıklama için teşekkürler, bu, $ parsers ve $ formatters arasındaki farkı anladığımdan çok daha mantıklı. –

9

Açısal 1.3'ten beri yeni yanıt $validators özelliği sağlar. 1.3, $parsers ve $formatters'dan beri, hala geçerli olsa bile, artık geçerliliğini ayarlamaları beklenmemektedir.

Sonra kod basit dönüşür: jsFiddle Güncelleme

myApp.directive('pastDate', function() { 
    return { 
     restrict: 'A', 
     require: '?ngModel', 
     link: function (scope, element, attrs, ctrl) { 
      ctrl.$validators.pastDate = function(modelValue) { // 'pastDate' is the name of your custom validator ... 
       var today = new Date(); 
       today = new Date(today.getFullYear(), today.getMonth(), today.getDate()); 
       return (new Date(modelValue) < today); 
      } 
     } 
    }; 
}); 

: http://jsfiddle.net/jD929/53/

+0

'$ validators' kullanarak, formumdaki diğer kapsam özelliklerine veya diğer alanlara nasıl erişebilirim? –

+0

Tüm gerekli öğelere 'link' işlevinin' scope', 'element', attrs' parametrelerini kullanarak erişebilirsiniz. Bu işlevin içinde olduğunuz gibi, bu öğeler mevcuttur. –

+0

Ancak, diğer form alanlarına erişemezsiniz. En azından basit bir şekilde değil. Ancak, teorik olarak, bir alanın geçerliliği diğer alan özelliklerine bağlı olmamalıdır. Hala gerekiyorsa, ana alan yönergesinde kaynak form özelliğinin bir "$ watch" (tüm forma sahip olanı) olarak ayarlamalısınız ve içinde, doğrulamanız gereken alanda bir özel özellik belirlemelisiniz. Daha sonra, doğrulayıcı, kendi özel olduğu sürece bu özel mülkü görebilir. Umarım yeterince açık olmak dileğiyle ... –

İlgili konular