2013-12-18 11 views
13

में निर्देशों में रैपिंग इनपुट मुझे विचार था कि मेरी साइट के माध्यम से एक निरंतर रूप और व्यवहार की गारंटी के लिए कस्टम निर्देशों में इनपुट लपेटें। मैं बूटस्ट्रैप यूई के डेटपिकर और ड्रॉपडाउन को भी लपेटना चाहता हूं। साथ ही, निर्देश सत्यापन और प्रदर्शन टूलटिप्स को संभालना चाहिए।कोणीय

<div> 
<div>..</div> //display validation in here 
<div>..</div> //add button to toggle datepicker (or other stuff) in here 
<div>..</div> //add input field in here 
</div> 

मैं विभिन्न तरीकों की कोशिश की:

<my-input required max-length='5' model='text' placeholder='text' name='text'/> 

या

<my-datepicker required model='start' placeholder='start' name='start'/> 
निर्देशों मैं एक डोम संरचना की तरह बनाना चाहते हैं, में

:

एचटीएमएल कुछ इस तरह दिखना चाहिए इसे प्राप्त करने के लिए लेकिन हमेशा कुछ ट्रेडऑफ में आया:

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

  2. केवल प्रतिस्थापन का उपयोग कर। इस मामले में, सभी विशेषताओं को बाहरीतम div पर लागू किया जाता है (भले ही मैं संकलन फ़ंक्शन में टेम्पलेट डोम संरचना उत्पन्न करता हूं)। यदि मैं केवल इनपुट के रूप में इनपुट का उपयोग करता हूं, तो गुण इनपुट पर हैं, लेकिन मुझे लिंक फ़ंक्शन में टेम्पलेट जेनरेट करने की आवश्यकता है, फिर उसे फिर से संकलित करें। जहां तक ​​मैं कोणीय के चरण मॉडल को समझता हूं, मैं लिंक फ़ंक्शन में टेम्पलेट डोम को पुनः संयोजित करने और बदलने से बचाना चाहता हूं (हालांकि मैंने कई लोगों को यह देखा है)।

वर्तमान में मैं दूसरे दृष्टिकोण के साथ काम कर रहा हूँ और लिंक समारोह में टेम्पलेट पैदा करने के लिए, लेकिन अगर किसी को कुछ बेहतर विचार था मैं सोच रहा था!

+0

कस्टम विशेषताओं किस तरह आप जोड़ने में सक्षम हो करना चाहते हैं? एचटीएमएल का एक पूरा उदाहरण आप चाहते हैं कि निर्देश (कस्टम अट्रीब और सभी) में प्रस्तुत करने का निर्देश यहां उपयोगी होगा, मुझे लगता है। –

+0

डेटपिकर के मामले में मैं आवेदन के व्यापक मानक मानों को व्यवस्थित करना चाहता हूं। परिणामी एचटीएमएल इनपुट टैग इस तरह दिखना चाहिए: '<इनपुट प्रकार =" टेक्स्ट "डेटा-डेटपिकर-पॉपअप =" "डेटा-ओपन-ओपन =" खोला गया "डेटा-वर्तमान-टेक्स्ट =" {{current}} "डेटा -close-text = "{{text}}" डेटा-स्पष्ट-पाठ = "{{clear}}" डेटा-शो-सप्ताह = "{{showweeks}}" डेटा-प्रारंभ-दिन = "{{startday}} "प्लेसहोल्डर =" {{प्लेसहोल्डर}} "डेटा-एनजी-मॉडल =" स्टार्ट "नाम =" स्टार्ट "आवश्यक =" आवश्यक "वर्ग =" एनजी-अलगाव-स्कोप एनजी-प्रिस्टिन एनजी-वैध एनजी-वैध-आवश्यक "> ' – roemer

उत्तर

2

ऐसा निर्देश क्यों नहीं दे रहा है?

myApp.directive('wrapForm', function(){ 
    return { 
     restrict: 'AC', 
     link: function(scope, inputElement, attributes){      
      var overallWrap = angular.element('<div />'); 
      var validation = angular.element('<div />').appendTo(overallWrap); 
      var button = angular.element('<div />').appendTo(overallWrap); 
      var inputWrap = angular.element('<div />').appendTo(overallWrap); 

      overallWrap.insertBefore(inputElement); 
      inputElement.appendTo(inputWrap); 

      inputElement.on('keyup', function(){ 
       if (inputElement.val()) { 
        validation.text('Just empty fields are valid!'); 
       } else { 
        validation.text(''); 
       } 
      });    
     } 
    } 
}); 

फिडल: http://jsfiddle.net/bZ6WL/

मूल रूप से आप मूल इनपुट क्षेत्र (जो, वैसे) लेने के लिए और कफन अलग से निर्माण। इस उदाहरण में मैं मैन्युअल रूप से डीआईवी का निर्माण करता हूं। अधिक जटिल सामग्री के लिए, आप एक टेम्पलेट का भी उपयोग कर सकते हैं जो $compile (डी) angularjs द्वारा प्राप्त करें।

इस वर्ग या HTML विशेषता "wrapForm" का उपयोग करने का लाभ: आप कई रूप इनपुट प्रकारों के लिए एक ही निर्देश का उपयोग कर सकते हैं।

+0

मैंने इसे बेवकूफ में देखा था लेकिन यह मेरे लिए काम नहीं कर रहा है, मुझे नहीं पता क्यों। मेरे पास मेरे आवेदन में jquery-1.10.2 और angular.js है और फिर भी यह काम नहीं करता !! –

+1

सावधान - यदि आप इसका उपयोग एनजी के साथ करते हैं- यदि यह रैपर को साफ़ नहीं करेगा! – jantimon

+0

यह एक अच्छा सुझाव है लेकिन कोणीय में संलग्न नहीं किया गया है या इससे पहले। एक समान परिणाम प्राप्त करने के लिए इसके बजाय और बाद में (क्रमशः) का उपयोग किया जा सकता है। – Theo

8

यहां मुझे विश्वास है कि ऐसा करने का उचित तरीका है। ओपी की तरह मैं एक input रैपर करने के लिए एक विशेषता निर्देश का उपयोग करने में सक्षम होना चाहता था। लेकिन मैं यह भी चाहता था कि यह ng-if के साथ काम करे और ऐसे में किसी भी तत्व को लीक किए बिना। जैसा कि @jantimon ने इंगित किया है, यदि आप अपने रैपर तत्वों को साफ़ नहीं करते हैं तो वे मूल तत्व को नष्ट कर देते हैं, तो वे एनजी के बाद रेंगेंगे।

app.directive("checkboxWrapper", [function() { 
    return { 
     restrict: "A", 
     link: function(scope, element, attrs, ctrl, transclude) { 
     var wrapper = angular.element('<div class="wrapper">This input is wrappered</div>'); 

     element.after(wrapper); 
     wrapper.prepend(element); 

     scope.$on("$destroy", function() { 
      wrapper.after(element); 
      wrapper.remove(); 
     }); 
     } 
    }; 
    } 
]); 

और here's a plunker आप साथ खेल सकते हैं।

महत्वपूर्ण: scope बनाम element $ नष्ट। आपको scope.$on("$destroy") में अपना क्लीनअप रखना होगा और element.on("$destroy") में नहीं होना चाहिए (जो मैं मूल रूप से प्रयास कर रहा था)। यदि आप इसे बाद वाले (तत्व) में करते हैं तो एक "ngIf end" टिप्पणी टैग लीक हो जाएगा। यह एंगुलर की एनजीआईएफ के आखिरी टिप्पणी टैग को साफ करने के बारे में है जब यह इसके झूठे तर्क को करता है। अपने निर्देशक के क्लीनअप कोड को दायरे में डालकर $ नष्ट कर दें, आप इनपुट को लपेटने से पहले डीओएम को वापस रख सकते हैं और इसलिए एनजी-अगर क्लीनअप कोड खुश है। उस समय तक element.on ("$ dest") कहा जाता है, यह एनजी में बहुत देर हो चुकी है-अगर झूठी प्रवाह मूल तत्व को बिना किसी टैग टैग रिसाव के अनचाहे करने के लिए प्रवाह करता है।

+1

[कोणीय के jqLite 'लपेटें' है] (https://docs.angularjs.org/api/ng/function/angular.element#angular-s-jqlite)। इसका उपयोग क्यों न करें 'बाद' और 'प्रीपेन्ड' बनाम? – TheSharpieOne

+0

'लपेटने' की कोशिश करने से मुझे कुछ कठिनाई हुई। निश्चित रूप से यह क्लीनर/दुबला वाक्यविन्यास होगा, लेकिन किसी कारण से 'wrap' का उपयोग करते समय सफाई कार्य नहीं करती है। प्लंकर में 'रैप' का प्रयास करें, फिर चेकबॉक्स को टॉगल करें (ngIf स्थिति को टॉगल करें)। मैं मानता हूं कि मैंने आगे की जांच नहीं की है, लेकिन अगर कोई इसमें आगे देखना चाहता है तो मुझे विवरण में दिलचस्पी है। – BrandonLWhite

2

संकलन फ़ंक्शन में इनपुट क्यों लपेटें? लाभ यह है कि आपको विशेषताओं की प्रतिलिपि बनाने की आवश्यकता नहीं होगी और स्कोप नष्ट करने के कार्य में सफाई करने की आवश्यकता नहीं होगी। ध्यान दें कि सर्कुलर निष्पादन को रोकने के लिए आपको निर्देश विशेषता को हटाना होगा।

(http://jsfiddle.net/oscott9/8er3fu0r/)

angular.module('directives').directive('wrappedWithDiv', [ 
    function() { 
     var definition = { 
      restrict: 'A', 
      compile: function(element, attrs) { 
       element.removeAttr("wrapped-with-div"); 
       element.replaceWith("<div style='border:2px solid blue'>" + 
        element[0].outerHTML + "</div>") 
      } 
     } 
     return definition; 
    } 
]); 
0

इस के आधार पर: http://angular-tips.com/blog/2014/03/transclusion-and-scopes/

यह निर्देश ट्रांसक्लुजन करता है, लेकिन transcluded सामान माता पिता गुंजाइश का उपयोग करता है, इसलिए सभी बाइंडिंग के रूप में काम करता है, तो transcluded सामग्री मूल में था दायरा जहां रैपर का उपयोग किया जाता है। इसमें निश्चित रूप से एनजी-मॉडल, न्यूनतम/अधिकतम और अन्य सत्यापन निर्देश/विशेषताएं शामिल हैं। किसी भी सामग्री के लिए काम करना चाहिए। मैं ng-transclude निर्देश का उपयोग नहीं कर रहा हूं क्योंकि मैं मैन्युअल रूप से तत्वों को क्लोन कर रहा हूं और माता-पिता (नियंत्रक) के दायरे को आपूर्ति कर रहा हूं। "my-transclude" का उपयोग ng-transclude के बजाय किया जाता है ताकि यह निर्दिष्ट किया जा सके कि स्थानांतरित सामग्री कहां डाली जाए।

बहुत खराब एनजी-ट्रांसफर में स्कोपिंग को नियंत्रित करने की सेटिंग नहीं है। यह सब इस अव्यवस्था को अनावश्यक बना देगा। और यह है कि वे इसे ठीक नहीं होगा दिखता है: https://github.com/angular/angular.js/issues/5489

controlsModule.directive('myWrapper', function() { 
     return { 
      restrict: 'E', 
      transclude: true, 
      scope: { 
       label: '@', 
       labelClass: '@', 
       hint: '@' 
      }, 

      link: link, 
      template: 
       '<div class="form-group" title="{{hint}}"> \ 
        <label class="{{labelClass}} control-label">{{label}}</label> \ 
        <my-transclude></my-transclude> \ 
       </div>' 
     }; 

     function link(scope, iElement, iAttrs, ctrl, transclude) { 

      transclude(scope.$parent, 
       function (clone, scope) { 

        iElement.find("my-transclude").replaceWith(clone); 

        scope.$on("$destroy", function() { 
         clone.remove(); 
        }); 
       }); 
     } 
    });