2013-11-27 15 views
17

मैं this SO answer explaining how to render a recursive JSON structure using a directive का पालन करने का प्रयास कर रहा हूं। हालांकि, प्रदान किए गए उत्तर के विपरीत, मेरा डेटा ज्ञात नहीं है जब डोम लोड होता है और कोणीय पहली बार चलता है।सेवा बदलते समय कोणीय जेएस निर्देश अद्यतन करना

इसके बजाय, मेरा डेटा एक HTML इनपुट फ़ील्ड से पुनर्प्राप्त किया जाता है और एक कोणीय सेवा में संग्रहीत किया जाता है (जब उपयोगकर्ता फॉर्म सबमिट करता है)।

सेवा के डेटा को संशोधित करते समय मैं एक कोणीय निर्देश को अद्यतित कैसे रख सकता हूं?


जवाब में अद्यतन जवाब देने के लिए

@musically_ut एक उत्कृष्ट जवाब यह है कि मदद की है प्रदान की है, लेकिन किसी समस्या से जूझ पता चला, एक कार्यान्वयन (यहाँ अद्यतन) को रोकने।

निर्देश एचटीएमएल कि कोणीय {{expressions}} जो $scope में संग्रहीत डेटा का उपयोग शामिल हो जाता है। चूंकि मूल समाधान $watch था जब सेवा में यह डेटा तैयार था।निर्देश निर्देशों से पहले $scopeमें 'नया' डेटा जोड़ा जा सकता है?

वास्तुकला और प्रवाह का अवलोकन है:

  1. ControllerA ->
  2. ControllerA उपयोगकर्ता से इनपुट प्राप्त करें - में परिवर्तन के लिए>$watch ->सेवा डेटा
  3. ControllerB को बदलने के लिए प्रयोग करें सेवा
  4. Directive ->$watch चा के लिए सेवा में nges
  5. ControllerB -> प्रदर्शन तब्दील डेटा (सेवा से) निर्देशों

समस्या चरण 5 और 6 के बीच है का उपयोग कर -> डेटा $scope

  • Directive में जोड़े। निर्देश{{expressions}} प्रस्तुत करता है इससे पहले कि नियंत्रक ने डेटा को $scope में जोड़ा है। यहां तक ​​कि अगर यह काम करता है, तो यह बहुत जटिल और 'हैकी' लगता है।

    असल में, प्रतिक्रिया करने के लिए, मैं नियंत्रक डेटा में $watch का उपयोग कर रहा हूं ताकि यह सुन सके कि परिवर्तित डेटा एक सेवा में कब तैयार है। यहां तक ​​कि यह थोड़ा ओवरकिल लगता है (सेवा कोई असीमित कॉल नहीं करता है)।

  • +0

    मैं कोणीय में नया हूँ, और निर्देशों में सेवाएं परिवर्तन देखने के बारे में जानकारी खोज करने के द्वारा पोस्ट करने के लिए मिलता है। जहाँ तक मेरा आप PB (और क्या मैं हाल ही में पढ़ा के अनुसार) को समझते हैं, आप नहीं में 'डेटा दायरे में जोड़ने के लिए' चाहिए अपने ** ControllerB **, तो आप बेहतर ** सेवा करने के लिए यह रिपोर्ट करना चाहिए **, और यह ** नियंत्रक बी ** स्कोप को स्वचालित रूप से सूचित किया जाएगा। वैसे, आप अपने ** निर्देश ** में ट्रैक करने के लिए ** सेवा ** परिवर्तन में सक्षम हो जाएगा (मैं पर नज़र रखने से आसानी से मतलब है 'बाहरी' ** controllerB ** गुंजाइश।) लेकिन शायद मैं गलत हूँ। –

    उत्तर

    17

    निर्देश को परिभाषित करते समय आप सेवा को इंजेक्ट कर सकते हैं और फिर डेटा पर $watch सेट अप कर सकते हैं।तो आपके मामले में:

    .directive('tree', function ($compile, myService) { 
        return { 
         // ... 
         link: function (scope, element, attrs) { 
          scope.$watch(function() { 
           return myService.getData(); 
          }, 
          function (newVal) { 
           if (typeof newVal !== 'undefined') { 
            // ... 
           } 
          } 
         }); 
        } 
    }); 
    

    यह बदलाव के लिए डेटा देख सकते हैं और कोड हर बार डाटा परिवर्तन चलेंगे।


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

    .directive('tree', function ($compile, myService) { 
        return { 
         // ... 
         link: function (scope, element, attrs) { 
          myService.getData().then(function (data) { 
           // ... 
          }, function (err) { 
           // Handle error 
          }); 
         } 
        } 
    }); 
    
    +1

    धन्यवाद। हालांकि, समस्या यह है कि ** निर्देश ** ** अभिव्यक्ति ** प्रस्तुत करता है जो $ क्षेत्र में JSON डेटा का उपयोग करता है। अपने ** निर्देश ** रन कोड जब ** सेवा ** अद्यतन, लेकिन क्या अगर यह ** सेवा ** डेटा $ दायरे में रखा जा सकता है इससे पहले कि चलाता है? ऐसा इसलिए होता है क्योंकि मेरा डेटा कंट्रोलर ए से पुनर्प्राप्त किया जाता है, लेकिन निर्देश नियंत्रक बी में प्रस्तुत किए जाते हैं। मैं नियंत्रक बी में 'myService.getData() 'देखता हूं और डेटा को $ स्कोप में सेट करता हूं। हालांकि, नियंत्रक बी अपडेट किए गए डेटा को $ स्कोप में जोड़ने से पहले मेरे निर्देश प्रस्तुत कर रहे हैं। – Jack

    0

    मैंने एक छोटा सा फ़ंक्शन लिखा है जो आपको बिना किसी स्थान के ऑब्जेक्ट में डेटा डालने देता है। आप इसे अपनी सेवा में उपयोग कर सकते हैं। इस तरह आपको घड़ी का उपयोग करने की आवश्यकता नहीं है। आप कोणीय के सामान्य पाचन लूप का उपयोग कर सकते हैं। ज़ोर परीक्षण साथ http://jsfiddle.net/y09kx7f7/1/

    नियंत्रक - JSFidde:

    app.controller('dem',function($scope,me){ 
        $scope.user=me.user; // {name:'user name'} 
    }) 
    

    नियंत्रक घड़ी हर बार बिना स्वचालित रूप से chnage किया जाएगा

    डेमो: उदाहरण के लिए, इस सरल नियंत्रक & सेवा देखना उपयोगकर्ता नाम बदल गया!

    सेवा

    .factory('me',function($timeout){ 
        var obj={} 
        obj.user={name:'hello'} 
        $timeout(function(){ //Example of change the data 
         newUser={name:'israel'} 
         cloneInto(obj.user,newUser) 
        },1000) 
        return obj 
    }) 
    

    cloneInto समारोह है कि मैं लिखा:

    // The function it is like a=b, 
    // but keeping the object in his original memory position. 
    function cloneInto(a,b){ 
        var i 
        for (i in a){ 
         if(typeof a[i]!='object') //For supporting deep-copy 
          delete a[i] 
        } 
        for (i in b){ 
         if (typeof b[i]=='object'){ 
          if(!a[i]) a[i]={} 
          cloneInto(a[i],b[i]) 
         } 
         else{ 
          a[i]=b[i] 
         } 
        } 
    } 
    
    संबंधित मुद्दे