2012-04-09 3 views
20

यदि बैकबोन व्यू अपनी रेंडर() विधि के अंदर नए दृश्य बनाता है, तो क्या इन दृश्यों को डेटा सदस्यों के रूप में बनाए रखा जाना चाहिए?Backbone.js - नेस्टेड दृश्यों को एक-दूसरे के संदर्भ बनाए रखना चाहिए?

render: function() { 
    var myView = new MyView({ model: values }); 
    $('div#value', this.el).append(myView.render().el); 
} 

के तरीकों प्रस्तुत करना चेनिंग इस प्रकार का मतलब यह है कि नेस्टेड दृश्य वास्तव में केवल बनाई गई है इतना है कि यह भी श्रृंखला किसी भी तरीकों से प्रस्तुत करना है और एक अच्छी तरह से निर्माण किया तत्व वापसी कर सकते हैं: एक ठेठ प्रस्तुत करना विधि की तरह दिखता है। मुझे लगता है कि कचरा संग्रह के लिए दृश्य छोड़ दिया गया है?

यदि नेस्टेड व्यू को संशोधित किया जाना है ... शायद भारी, क्या इसे अभी बनाया जाना चाहिए, या इसे डेटा-सदस्य संदर्भ के माध्यम से संशोधित किया जाना चाहिए?

मेरी समस्या यह है कि नेस्टेड दृश्य उन घटनाओं को प्राप्त करते हैं जिनके लिए उन्हें अपने स्वयं के नेस्टेड दृश्यों को संशोधित करने की आवश्यकता होती है, और कभी-कभी उनके माता-पिता दृश्य।

मैं वास्तव में हर जगह चारों ओर श्रोताओं को फेंकना शुरू नहीं करना चाहता हूं। और माता-पिता के दृश्यों के संदर्भ में गुजरना और बच्चे से रेंडर() कहा जाता है, परिणामस्वरूप मेमोरी रिसाव में परिणाम देखें क्योंकि माता-पिता एक नया बच्चा बनाता है जबकि मूल बच्चा देखें अपने माता-पिता के संदर्भ को बनाए रखता है!

फिलहाल यह बहुत ढांचा नहीं है। क्या किसी के पास कोई संसाधन है जो मुझे इस समस्या को फ्रेम-कार्य में हल करने में मदद करेगा?

+1

क्लोजर और वस्तुओं कोई लाइव संदर्भ या बाइंडिंग उन्हें कहीं भी है कि एक स्मृति रिसाव का कारण नहीं बनेगा सिर्फ इसलिए कि वे मौजूदा कुछ करने के लिए संदर्भ है, कम से कम (अनिवार्य रूप से होना करने के लिए कचरा एकत्र प्रतीक्षा में), किसी भी कचरा संग्रहण योजना में नहीं, मुझे पता है ... निश्चित रूप से कुछ कचरा संग्रह इंजन चक्रीय संदर्भों के साथ अच्छी तरह से काम नहीं करेंगे (मैन्युअल रूप से संदर्भों को संभाले बिना) लेकिन जावास्क्रिप्ट मार्क-एंड-स्वीप का उपयोग करता है, और जो चक्रीय संदर्भों को ठीक करता है । एएफएआईके सबसे खराब समस्याएं डीओएम और जावास्क्रिप्ट "दुनिया" के बीच पार संदर्भों के कारण हुई हैं। – JayC

उत्तर

44

(चेतावनी: मेरा उत्तर एक tl बन गया, डॉ ग्रंथ)

मैं जल्दी पर ये एक ही सवाल के कुछ था, और आदेश में कुछ बहुत जटिल क्षुधा बनाने के लिए अपना होमवर्क किया है, इसलिए मैं प्रदान करेंगे मेरा दृष्टिकोण।

रीढ़ की हड्डी सीखने के साथ बड़ी चुनौती यह है कि यह इतना अनौपचारिक है और कई अलग-अलग तरीकों से (और है) का उपयोग किया जा सकता है, यह समझना मुश्किल है कि कुछ "सही" या कम से कम एक अच्छे तरीके से कैसे करना है आप शुरू कर रहे हैं रीढ़ की हड्डी का उपयोग करने का सिर्फ एक सही तरीका नहीं है, लेकिन इसकी लचीलापन लगभग किसी भी ऐप के लिए एक शानदार संरचना बनाती है, और उम्मीद है कि मैं कुछ मार्गदर्शन प्रदान करने में मदद कर सकता हूं। (मैं शायद यहां हर वाक्य में "आईएमओ" संलग्न कर सकता हूं)।

पहले, रीढ़ की हड्डी की मेरी समझ विचार

रीढ़ क्षुधा में, वहाँ दृश्यों का उपयोग करने के लिए उपयोगी तरीके का एक बहुत हैं। मैं आमतौर पर अपने ऐप्स में कुछ ओवरलैपिंग प्रकार के विचार देखता हूं:

मेरे पास आमतौर पर एक या अधिक "रूट-स्तर" दृश्य होते हैं। रूट-स्तरीय विचार प्रायः पृष्ठ के विशिष्ट हिस्सों को संभालने वाले बच्चों के विचारों को प्रारंभ करने, प्रस्तुत करने और संदर्भ रखने के लिए एक स्थान होते हैं। रूट-लेवल व्यू के el अक्सर शरीर के भीतर "शरीर" या अन्य उच्च स्तरीय तत्व होता है। कुछ मामलों में, रूट-स्तरीय दृश्य का अपना HTML निरीक्षण और/या प्रस्तुत करने के लिए होता है। दूसरों में, रूट-स्तरीय दृश्य में el नहीं हो सकता है और केवल बच्चे के विचारों का प्रबंधन करता है। मैं वैश्विक 'ऐप' नेमस्पेस ऑब्जेक्ट में प्रत्येक रूट-स्तरीय दृश्य (अक्सर केवल एक) का संदर्भ रखता हूं।

"रूट-स्तर" दृश्यों के अतिरिक्त, आमतौर पर "बाल दृश्य" होते हैं। एक बच्चे का दृश्य प्रारंभ होता है और "पैरेंट" व्यू द्वारा प्रस्तुत किया जाता है, जो रूट-स्तरीय दृश्य या कोई अन्य बच्चा दृश्य हो सकता है। माता-पिता के विचारों को ऐप के रूप में प्रारंभ करने, प्रतिपादन करने, छिपाने, दिखाने, और/या अपने बच्चों को नष्ट करने का प्रभारी होता है। कभी-कभी अभिभावक दृश्य किसी बच्चे के दृश्यों की एक चरणीय संख्या का ट्रैक रख सकता है (उदा।, प्लेलिस्ट व्यू में एन सॉन्ग व्यू हैं)। अक्सर, माता-पिता बच्चों के संदर्भ बनाए रखते हैं, लेकिन कभी-कभी यह अनावश्यक है (नीचे इस पर अधिक)।

'रूट-लेवल/पैरेंट/बच्चे' प्रतिमान के अलावा, मुझे विचारों को दो श्रेणियों में से एक में फिट करना पड़ता है: (1) स्थिर: जिसका अर्थ है कि दृश्य प्रारंभ होने के बाद, दृश्य और इसकी el छड़ी चारों ओर, भले ही सामान इसके अंदर बदल जाए; और (2) गतिशील, जो विभिन्न घटनाओं के आधार पर आते हैं और जाते हैं। आम तौर पर, मेरे रूट-स्तरीय दृश्य हमेशा स्थिर होते हैं। वे आम तौर पर मौजूदा डीओएम तत्व, जैसे 'बॉडी' या '# my-div' से मेल खाते हैं। बाल विचार अक्सर गतिशील होते हैं, लेकिन स्थिर भी हो सकते हैं। (। सुझाव: el: '#element-id' का उपयोग जब एक स्थिर दृश्य की घोषणा el के रूप में एक मौजूदा DOM एलीमेंट उपयोग करने के लिए गतिशील दृश्य आम तौर पर एक मौजूदा el निर्दिष्ट नहीं करते हैं, वे tagNameid और className का उपयोग तत्व यह है कि गतिशील दृश्य उत्पन्न होगा वर्णन करने के लिए।)

दृश्यों में अनिवार्य रूप से 3 कार्य होते हैं: (1) अपने माता-पिता द्वारा या घटनाओं के जवाब में (या रूट-स्तरीय दृश्य के मामले में, राउटर या 'मुख्य द्वारा प्रारंभ किए जाने पर स्वयं को और उनके बच्चों को प्रस्तुत करते हैं 'फ़ंक्शन, इत्यादि), (2) मॉडलों या संग्रहों को अपडेट करके या कस्टम बैकबोन घटनाओं को ट्रिगर करके, और उनके जवाब को el (लेकिन किसी भी बच्चे के दृश्य के el के भीतर) के भीतर डीओएम तत्वों से यूआई घटनाओं का जवाब दें, और (3) देखें और जवाब दें बैकबोन (मोड एल, संग्रह, इत्यादि) ऐसी घटनाएं जिन्हें उनके एल के भीतर कुछ प्रस्तुत करने या बदलने की आवश्यकता होती है (लेकिन किसी भी बच्चे के दृश्य के भीतर नहीं।) कभी-कभी उपयोगी चाल यह है कि बच्चे के विचार स्वयं पर घटनाओं को ट्रिगर कर सकते हैं (this.trigger('customEvent')) कि माता-पिता विचार देख सकते हैं (childView.on('customEvent', this.handler, this))।

रीढ़ की हड्डी के दृश्य पैटर्न पर अतिरिक्त दिलचस्प दृष्टिकोण के लिए देखें: this और this

अब उस संदर्भ में, सवाल

1) कचरा संग्रहण, गुंजाइश, और स्मृति के के डर से लीक

आप माता-पिता में एक स्थानीय वर के रूप में एक बच्चे को देखने का दृष्टांत हैं रेंडर करने के लिए पर (या अन्य) विधि और इसे प्रस्तुत करें, और फिर कार्य गुंजाइश से बाहर हो जाता है, मैं कचरा संग्रह के डर को समझ सकता हूं या यह दृश्य ऐसा करने में सक्षम नहीं होगा जो उसे करने की ज़रूरत है। कचरा कलेक्टर, बस लाश से डरने की कोई ज़रूरत नहीं है। यदि आपके दृश्य में कोई भी ईवेंट हैंडलर है, चाहे यूआई इवेंट हैंडलर ने "घटनाओं" घोषणा में घोषित किया है, या अन्य बैकबोन ऑब्जेक्ट्स इवेंट्स या अन्य डोम-आधारित ईवेंट श्रोताओं के लिए बाध्यकारी घोषित किया है, तो आपका विचार कचरा नहीं होगा, भले ही आप ' टी के पास इसका कोई संदर्भ नहीं है - यह अभी भी स्मृति में मौजूद होगा और घटनाओं का जवाब देगा। दूसरी तरफ, यदि किसी दृश्य में कोई ईवेंट हैंडलर नहीं है, तो इसका एकमात्र काम तत्व को प्रस्तुत करना है, इसलिए कौन परवाह करता है कि जावास्क्रिप्ट ऑब्जेक्ट जो इसे प्रस्तुत करता है, यह शायद कचरा हो जाएगा क्योंकि यह होना चाहिए क्योंकि यह होना चाहिए । जेएस कचरा संग्रह की सामान्य समझ के लिए this देखें और यह बैकबोन.जेएस से कैसे संबंधित है।

बड़ी चिंता Zombie views है। यदि विचारों को डीओएम से हटाया जाना है और अनिवार्य रूप से आपके ऐप में किसी बिंदु पर त्याग दिया गया है, तो सुनिश्चित करें कि वे या तो स्वयं को पूरी तरह से हटा दें या माता-पिता के विचारों को उनके संदर्भ में रखना चाहिए और उन्हें हटा देना चाहिए। और उन विचारों को दोबारा बनाएं और बदलें जिन्हें पहले से ही बनाया गया है और ठीक से हटाया नहीं गया है। हटाने पर .remove() को कॉल करके निष्पादित किया जाता है, साथ ही on(...) का उपयोग करके off(...) का उपयोग करके किसी भी बाहरी बैकबोन ईवेंट को अनबाइंड करना। रीबोटाइप के "listenTo" and "stopListening" methods को जोड़कर बैकबोन के हाल के संस्करण (1.0+) इस समस्या को अधिक आसानी से संबोधित करते हैं। यदि आप गतिशील रूप से DOM से और दृश्यों को जोड़ रहे हैं, तो इन तरीकों को समझें और बंद करें। युक्ति: a hacky jquery "remove" event like this one सेट अप करने से दृश्यों को आसानी से हटाया जा सकता है जब उनके el को DOM से हटा दिया जाता है (यदि आपके ऐप प्रवाह में कोई ईवेंट नहीं है जो एक ही उद्देश्य को पूरा कर सकता है)।

2) क्या बच्चों के विचारों को मूल विचारों के डेटा सदस्यों के रूप में बनाए रखा जाना चाहिए?

यह निर्भर करता है। मुझे नहीं लगता कि सीमित उद्देश्यों के लिए उनके बच्चे के विचारों के बारे में माता-पिता के विचारों को जागरूक होना एमवीसी के किसी सुनहरे सिद्धांतों का उल्लंघन करता है। कभी-कभी, माता-पिता को विशिष्ट बाल दृश्य उदाहरणों के सदस्य संदर्भ होते हैं, यदि आपको इसकी आवश्यकता होती है तो बच्चे के विचारों को प्रबंधित करने का एक शानदार तरीका है। जैसा कि मैंने संकेत दिया है, कभी-कभी अभिभावक विचार उन घटनाओं का जवाब देते हैं जिनके लिए उन्हें अपने बच्चों के विचारों को प्रस्तुत करने, पुनः प्रस्तुत करने, छिपाने या हटाने की आवश्यकता होती है। कभी-कभी वे ऐसी घटनाओं को सुनना चाह सकते हैं जो बच्चे के विचार खुद पर ट्रिगर करते हैं। हालांकि, माता-पिता को अपने बच्चे के विचारों 'el' के अंदर कुछ भी शामिल नहीं होना चाहिए।

ने कहा, इन प्रकार के संदर्भों का अधिक उपयोग न करें। कई बार, आपको बच्चों के विचारों के संदर्भों का उपयोग करने की आवश्यकता नहीं होगी, क्योंकि बच्चे स्वयं का ख्याल रख सकते हैं। जैसा कि मैंने उल्लेख किया है, विचारों को एक बार प्रस्तुत किया गया है, केवल ए चाहिए) अपने एल के अंदर यूआई घटनाओं के लिए देखें (लेकिन आम तौर पर किसी भी बच्चे के दृश्य के अंदर नहीं) और मॉडल या संग्रह अपडेट करें या इन यूआई घटनाओं के जवाब में घटनाओं को ट्रिगर करें, या बी) के लिए देखें अन्य रीढ़ की हड्डी वस्तुओं (आमतौर पर मॉडल या संग्रह या अन्य विचार) से घटनाएं और प्रतिक्रिया में कार्रवाई करें (उदाहरण के लिए, अपने स्वयं के यूआई तत्वों को अपडेट करें)। कई मामलों में, एक दृश्य स्वयं का ख्याल रख सकता है और खुद को भी हटा सकता है। यदि कोई अन्य व्यू या अन्य बैकबोन ऑब्जेक्ट आपके दृश्य में होने वाली यूआई घटना के बारे में परवाह करता है, तो मॉडल को अपडेट करें या दृश्य पर एक ईवेंट ट्रिगर करें और उन्हें इसे देखने दें। इसी तरह, अगर आपके दृश्य के बाहर कुछ आपके दृश्य में अद्यतन प्रतिपादन की आवश्यकता है, तो मॉडल में बदलाव की सुनें या संबंधित कस्टम ईवेंट पर प्रतीक्षा करें। एक सामान्य सिद्धांत के रूप में, माता-पिता को अपने बच्चों को दिमाग में समझने के अपवाद के साथ विचारों को एक-दूसरे से अनजान होना चाहिए।

3) क्या बच्चे के विचार माता-पिता के विचारों के संदर्भ बनाए रखना चाहिए?

नहीं। कभी नहीं। मैं एक ऐसे परिदृश्य के बारे में नहीं सोच सकता जहां आपको किसी ऐसे माता-पिता के संदर्भ के माध्यम से कुछ हासिल करने की आवश्यकता होगी जिसे माता-पिता देख रहे मॉडल को बदलकर या किसी ईवेंट को ट्रिगर करके पूरा नहीं किया जा सकता है (उदाहरण के लिए, एक कस्टम इवेंट कह रहा है "हे, एक्स हुआ") बच्चे को स्वयं या किसी अन्य रीढ़ की हड्डी "घटनाक्रम" आधारित वस्तु पर देखते हैं। बैकबोन में, मैं अपने डेटा और मेरे राज्य दोनों का प्रतिनिधित्व करने के लिए मॉडल का उपयोग करता हूं। तो अगर किसी ऐसे दृश्य में कुछ होता है जो मेरे आवेदन की स्थिति को बदलता है, तो मैं मॉडल के संबंधित राज्य विशेषता को बदलता हूं और अन्य विचारों (माता-पिता समेत) को स्वचालित "परिवर्तन" ईवेंट सुनता हूं, यदि वे परवाह करते हैं। मैं ऐप में घटनाओं को ट्रिगर करने और सुनने के लिए एक वैश्विक "वेंट" बस जैसी वस्तु (केवल एक मूल जावास्क्रिप्ट ऑब्जेक्ट जो बैकबोन.इवेंट्स को बढ़ाता है) का उपयोग करता हूं, और कभी-कभी मैं खुद को दृश्यों पर ट्रिगर करता हूं ताकि माता-पिता को यह पता चल सके कि कुछ हुआ । जो कुछ भी काम करता है, वैसे ही अपने वास्तुकला को यथासंभव उलझन में रखते हुए।

4) मैं वास्तव में हर जगह चारों ओर श्रोताओं को फेंकना शुरू नहीं करना चाहता हूं।

खैर मुझे लगता है कि रीढ़ की हड्डी के बारे में एक अच्छी बात है कि आप की जरूरत नहीं है कि है, लेकिन पता है कि पर्यवेक्षक पैटर्न (यानी घटनाओं & श्रोताओं) और ढीला संयोजन MVC की रीढ़ की हड्डी के स्वाद के दिल में हैं है (ध्यान दें कि हर एकल बैकबोन कक्षा घटनाओं को फैलाता है?), और अधिकांश लोग तदनुसार इसका उपयोग करते हैं।

संदर्भ?

मैं दृढ़ता से PeepCode tutorials की अनुशंसा करता हूं जब तक आपको लगता है कि आप पहले से ही एक सुंदर उन्नत स्तर पर नहीं हैं। 12 रुपये एक टुकड़ा है, लेकिन आपको पहले एक या दूसरे & के साथ शुरू करने की आवश्यकता है, यह बहुत उपयोगी नहीं होगा।

इसके अलावा, here's a nice overview

अंत

+0

धन्यवाद। वह अविश्वसनीय रूप से सहायक था। – user941521

+0

अच्छी तरह से रखो, @ बेन आर! +1: डी –

+1

"यदि आपके दृश्य में कोई भी ईवेंट हैंडलर है ... यह कचरा नहीं होगा, भले ही आपके पास इसका कोई संदर्भ न हो - यह अभी भी स्मृति में मौजूद होगा और घटनाओं का जवाब देगा।" इकाई परीक्षण लिखते समय ध्यान में रखना कुछ! –

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