2016-09-26 18 views
7

मेरे पास एक अभिभावक/बाल घटक सेटअप है जहां माता-पिता सर्वर से डेटा लोड कर रहा है और इसे प्रोप के माध्यम से बच्चों को पास कर रहा है। बच्चे में मैं एक jQuery कैलेंडर को तत्काल प्राप्त करना चाहता हूं जिसमें यह माता-पिता से प्राप्त कुछ डेटा के साथ होता है।VueJs बाल घटक प्रोप तुरंत अद्यतन नहीं कर रहा है

कैलेंडर सेट करने से पहले डेटा की प्रतीक्षा करने के लिए, मैंने माता-पिता में एक ईवेंट प्रसारित किया कि मेरे पास बच्चे में ईवेंट श्रोता सेटअप है।

श्रोता को बच्चे में निकाल दिया जा रहा है लेकिन यदि मैं this.$log('theProp'), यह अपरिभाषित है। हालांकि, अगर मैं VueJs devtools के साथ घटकों का निरीक्षण करता हूं, तो मूल/बाल संबंध वहां होता है और इस दौरान बच्चे को प्रोप प्राप्त हुआ है।

प्रोप को बच्चे को गतिशील प्रोप :the-prop="theProp" के रूप में परिभाषित किया गया है। चूंकि बच्चे को अंत में प्रोप प्राप्त होता है, इसलिए मुझे लगता है कि मेरा सेटअप सही है लेकिन कुछ प्रकार की देरी होती है। अभिभावक अजाक्स कॉल के रिटर्न फ़ंक्शन में प्रोप सेट करता है और फिर: यह काम कर रहा है, बस थोड़ी देर के साथ ऐसा लगता है।

मैंने बच्चे में प्रोप पर watch श्रोता पंजीकरण करने का भी प्रयास किया ताकि मैं कैलेंडर सेट कर सकूं और सुनिश्चित कर सकूं कि प्रोप वहां है। हालांकि, घड़ी श्रोता आग लगती है, लेकिन this.$log('theProp') अभी भी अपरिभाषित है।

यदि मैं प्रसारण कॉल के साथ डेटा पास करता हूं, जैसे this.$broadcast('dataLoaded', theData) बच्चे को यह ठीक लगता है। लेकिन ऐसा लगता है कि मैं मूल रूप से अपने स्वयं के प्रोप हैंडलर का निर्माण कर रहा हूं।

मैं कोई कोड पोस्ट नहीं कर रहा हूं क्योंकि घटक बड़े हैं और VueJs devtools मुझे बता रहे हैं कि माता-पिता/बच्चे की स्थिति काम कर रही है।

क्या मुझे कुछ जानकारी याद आ रही है? माता-पिता में मूल्य निर्धारित करने और बच्चे को प्राप्त करने के बीच थोड़ी देर हो रही है? बच्चे में अभिभावक डेटा की प्रतीक्षा करने का उचित तरीका क्या होगा?

आम तौर पर, जब आप टेम्पलेट में डेटा को केवल प्रस्तुत कर रहे होते हैं, तो डेटा टेम्पलेट से बाध्य होने के बाद से कोई फर्क नहीं पड़ता। लेकिन इस मामले में, मुझे कैलेंडर सेट अप करने के लिए वास्तव में डेटा की आवश्यकता है या यह गलत होगा।

धन्यवाद।

संपादित करें 1: https://jsfiddle.net/dr3djo0u/1/ यह पुष्टि करते हैं कि डेटा तुरंत प्रसारण के बाद उपलब्ध नहीं है लगता है: यहाँ एक jsfiddle है। हालांकि, वॉचर काम करता है, हालांकि मैं लगभग कसम खाता हूं कि कभी-कभी this.$log('someData')undefined लौटाता है जब मैं उस टेस्टकेस को सेटअप करता हूं।

लेकिन मुझे लगता है कि मेरी समस्या कहीं और हो सकती है, मैं आज रात देखूंगा, मेरे पास अभी परियोजना नहीं है।

संपादित करें 2: ने कुछ और परीक्षण किए। मेरी समस्या यह थी कि ए) ईवेंट श्रोताओं को तत्काल डेटा प्राप्त नहीं होता है और बी) route.data कॉलबैक में कैलेंडर को init करने का भी प्रयास कर रहा था अगर someData पहले से ही था (उदाहरण के लिए जब माता-पिता से आ रहा है), लेकिन उस मार्ग कॉलबैक को कॉल किया जाता है घटक तैयार होने से पहले, इसलिए यह वहां काम नहीं कर रहा था।

मेरे समाधान अब है यह:

// works when the child route is loaded directly and parent finishes loading someData 
watch: { 
    someData() { 
     this.initCalendar(); 
    } 
}, 

// works when navigating from parent (data already loaded) 
ready() { 
    if (this.someData && this.someData.length) { 
     this.initCalendar() 
    } 
} 
+1

हाय आप एक प्रदान कर सकते हैं इस मुद्दे को पुन: उत्पन्न करने के लिए सरल कोड उदाहरण? – Nora

+2

यदि आप एक चर देख रहे हैं और 'घड़ी' के अंदर उसका मान अपरिभाषित है, तो वास्तव में इसे अपरिभाषित करने के लिए कुछ सेट कर रहा है। –

+0

आपकी टिप्पणियों के लिए धन्यवाद। मेरे प्रश्नों को अपडेट किया गया जो मैंने पाया। – Chris

उत्तर

3

जहाँ तक मुझे पता है, आप माता-पिता से बच्चे को डेटा पास करने की घटनाओं की जरूरत नहीं होनी चाहिए।props: ['theProp']

और जब माता-पिता में बच्चे घटक का उपयोग: <child :theProp="someData"></child>

अब, जहाँ भी माता-पिता आप someData बदलने में, बच्चे घटक तदनुसार प्रतिक्रिया होगी

आपको बस बच्चे घटक में, है

आपको घटनाओं की आवश्यकता नहीं है, आपको "घड़ी" की आवश्यकता नहीं है, आपको "तैयार" की आवश्यकता नहीं है।


उदाहरण के लिए: एक AJAX कॉल के बाद, में माता-पिता के "तैयार", आप कुछ डेटा लोड:

// at the parent component 

data: function() { 
    return { 
    someData: {} 
    } 
}, 

ready: function() { 
    var vm = this; 
    $.get(url, function(response) { 
    vm.someData = response; 
    }); 
} 
अब

, आप बच्चे के लिए डेटा पास करने के कुछ और की जरूरत नहीं है। यह पहले से ही बच्चे में theProp है!

आपको वास्तव में क्या करने की ज़रूरत है, बच्चे में, पर अपने theProp संपत्ति पर डेटा परिवर्तनों के लिए प्रतिक्रिया करता है।

इंटरफ़ेस में कोई एक:

<div v-if="theProp.id > 0"> 
    Loaded! 
</div> 

या जावा स्क्रिप्ट कोड में:

// at the child component 

computed: { 
    // using a computed property based on theProp's value 
    awesomeDate: function() { 
    if (!this.theProp || (this.theProp.length === 0)) { 
     return false; 
    } 
    if (!this.initialized) { 
     this.initCalendar(); 
    } 
    return this.theProp.someThing; 
    } 
} 

अद्यतन 1

तुम भी, माता पिता में, बच्चे प्रदान कर सकते हैं सशर्त रूप से:

<child v-if="dataLoaded" :theProp="someData"></child> 

डेटा उपलब्ध होने पर केवल dataLoaded पर सेट करें।

अद्यतन 2

या हो सकता है आपकी समस्या का एक change detection caveat

हो सकता है कि आप एक वस्तु में एक नया संपत्ति बना रहे हैं से संबंधित है ...

vm.someObject.someProperty = someValue 

... जब आपको करना चाहिए ...

vm.$set('someObject.someProperty', someValue) 

... अन्य "चेतावनी" के बीच।

अद्यतन 3

VueJS 2 में आप टेम्पलेट्स के लिए सीमित नहीं हैं। आप render function का उपयोग कर सकते हैं और सबसे जटिल रेंडरिंग तर्क कोड को कोड कर सकते हैं।

अद्यतन 4 (के बारे में ओ पी के संपादित 2)

शायद तुम ready ड्रॉप और immediate विकल्प का उपयोग कर सकते हैं, तो आपके प्रारंभ एक ही स्थान में है:

watch: { 
    someData: { 
    handler: function (someData) { 
     // check someData and eventually call 
     this.initCalendar(); 
    }, 
    immediate: true 
    } 
} 
+0

मैं प्रोप के माध्यम से डेटा पास कर रहा हूं, मेरा प्रश्न डेटा परिवर्तन प्राप्त करने पर प्रतिक्रिया करने के संबंध में है, क्योंकि मुझे इसके आधार पर चीजों को ध्यान में रखना है। गणना की गई संपत्तियां उस तरह की चीज़ इमो के लिए जाने का तरीका नहीं हैं। – Chris

+0

मैंने अपने उत्तरों को अन्य सुझावों सहित अपडेट किया है। फिर भी, imho, गणना गुण इस मामले के लिए एक अच्छा फिट हैं। आप 'someData' पर आधारित 'isReady' या' isLoaded 'गणना की गई संपत्ति बना सकते हैं। वास्तव में, यदि आपको डेटा परिवर्तनों पर प्रतिक्रिया करने की आवश्यकता है, तो एक गणना की गई संपत्ति ** ** जाने का तरीका है। टेम्पलेट्स का उपयोग करते समय –

+0

, हां। एक विधि में, यदि मैं 'if (this.isLoaded) 'की जांच करता हूं और यह उस समय लोड नहीं होता है, तो मुझे कैलेंडर को तुरंत चालू करने का अवसर याद आती है। इस प्रकार, मुझे अपने दूसरे अपडेट में वर्णित परिवर्तनों के लिए डेटा देखना होगा। अच्छा काम करता है। – Chris

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