2013-07-12 7 views
15

मैंने अतीत में होने वाली तारीख की आवश्यकता के लिए एक कस्टम सत्यापनकर्ता बनाया है। मैन्युअल रूप से फ़ील्ड में दिनांक दर्ज करते समय सत्यापन बहुत अच्छा लगता है। हालांकि, अगर मैं प्रोग्राम को दिनांकित रूप से बदलता हूं (क्षेत्र में टाइपिंग के विपरीत मॉडल को सीधे बदलें), तो सत्यापन आग नहीं आता है।कोणीय जेएस कस्टम सत्यापन मॉडल प्रोग्रामेटिक रूप से बदलते समय फायरिंग नहीं

मेरा मानना ​​है कि मैं प्रलेखन में निर्देशित कस्टम सत्यापन निर्देश कर रहा हूं। Here is a jsFiddle समस्या का वर्णन। बेवकूफ में, यदि आप "प्रोग्राम दिनांक बदलें" बटन पर क्लिक करते हैं, तो आप देख सकते हैं कि सत्यापन त्रुटि प्रदर्शित नहीं होती है (लेकिन यदि आप इसे मैन्युअल रूप से बदलते हैं तो यह करता है)।

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; 
      }); 
     } 
    }; 
}); 

उत्तर

18

वहाँ $formatters नियंत्रण बाइंडिंग, $parsers नियंत्रण दृश्य करने वाली मॉडल दिशा की पाइप लाइन मॉडल के दो तरीके, और मॉडल करने की पाइप लाइन कर रहे हैं: यहाँ निर्देश कोड (भी बेला में) है -व्यू दिशा। जब आप नियंत्रक में मॉडल को अपडेट करते हैं, तो परिवर्तन $formatters पाइपलाइन के माध्यम से जाता है।

मैंने आपका कोड अपडेट किया है: this, इसलिए यह दोनों तरीकों से संभालता है।

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

फेलिक्स :) – Terry

+1

@Terry हाँ, दुर्भाग्य से आप कार्यालय में केक को याद करने जा रहे हैं आज ही उसमें मुझे हराया। – yuxhuang

+0

स्पष्टीकरण के लिए धन्यवाद, यह अब और अधिक समझ में आता है कि मैं $ पार्सर्स और $ फॉर्मेटर्स के बीच अंतर को समझता हूं। –

9

कोणीय 1.3 के बाद से नया उत्तर $validators संपत्ति प्रदान करता है।

1.3, $parsers और $formatters से अब वैधता निर्धारित नहीं की जानी चाहिए, भले ही यह अभी भी संभव हो।

फिर अपने कोड सरल हो जाता है:

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); 
      } 
     } 
    }; 
}); 

अपडेट किया गया jsFiddle: http://jsfiddle.net/jD929/53/

+0

'$ validators' का उपयोग करके, मैं अपने फॉर्म में अन्य स्कोप गुणों या अन्य फ़ील्ड तक कैसे पहुंच सकता हूं? –

+0

आप 'लिंक' फ़ंक्शन के 'स्कोप', 'element', 'attrs' पैरामीटर का उपयोग कर सभी आवश्यक तत्वों तक पहुंच सकते हैं। जैसा कि आप इस फ़ंक्शन के अंदर हैं, ये तत्व उपलब्ध हैं। –

+0

हालांकि, आप अन्य फॉर्म फ़ील्ड तक नहीं पहुंच सकते हैं। कम से कम एक आसान तरीके से नहीं। लेकिन, सिद्धांत रूप से, किसी क्षेत्र की मान्यता अन्य फ़ील्ड गुणों पर निर्भर नहीं होनी चाहिए। यदि आपको अभी भी आवश्यकता है, तो आपको पैरेंट डायरेक्टिव (सभी फॉर्म के साथ एक) में स्रोत फ़ील्ड प्रॉपर्टी का '$ watch' सेट करना चाहिए और भीतर, उस क्षेत्र में एक कस्टम प्रॉपर्टी सेट करें जिसे आपको सत्यापित करने की आवश्यकता है। तब आपका सत्यापनकर्ता इस कस्टम प्रॉपर्टी को देख पाएगा, जब तक कि यह स्वयं का हो। उम्मीद है कि पर्याप्त स्पष्ट हो रहा है ... –

संबंधित मुद्दे