2012-11-20 15 views
6

यह एसओ पर मेरा पहला सवाल है इसलिए मुझे उम्मीद है कि मैं गड़बड़ नहीं कर रहा हूं। मैंने इस समस्या पर अन्य विषयों की जांच की है, लेकिन वे मेरे मामले में शामिल नहीं हैं।रीढ़ की हड्डी के दृश्य को विस्तारित करना और साफ तरीके से विकल्पों का उत्तराधिकारी

मैं मोबाइल एप्लिकेशन बनाने के लिए बैकबोन के शीर्ष पर एक लाइब्रेरी का निर्माण कर रहा हूं। मुख्य कारण यह है कि मैं रीढ़ की हड्डी के दृश्यों के रूप में सभी घटकों को परिभाषित कर रहा हूं क्योंकि मैं स्क्रॉलिंग पर स्मृति अनुकूलन करना चाहता हूं (सामान छिपाना/डीओएम से सामान निकालना)।

मुझे सिर्फ एक defenition कि सबसे आदर्श स्थिति अन्य घटकों कुछ डिफ़ॉल्ट के साथ, का उपयोग करने के लिए गुण और कुछ आसान तरीकों कि मैं हर घटक पर जरूरत

एक आधार वर्ग को परिभाषित किया जाएगा के साथ शुरू करते हैं।

UI.Component = Backbone.View.extend({ 
    viewOptions: ['children'], 

    children: [], 

    add: function(child) { 
     this.children.push(child); 
    } 
}); 

कुछ डिफ़ॉल्ट गुण

UI.Header = UI.Component.extend({ 
    viewOptions: ['titleBarChildren', 'secondaryBarChildren', 'title', 'backButtonTitle'], 

    titleBarChildren: [], 

    secondaryBarChildren: [], 

    title: '', 

    backButtonTitle: 'Back' 
}); 

एक डिफ़ॉल्ट शीर्ष लेख बनाने के साथ एक घटक को परिभाषित करें अपने आवेदन

MyApp.Headers.Default = UI.Header.extend({ 
    backButtonTitle: 'Terug', 

    titleBarChildren: [ 
     new UI.SegmentedController({ 
      children: [ 
       new UI.Button('Lame example') 
      ] 
     }) 
    ] 
}); 

में उपयोग करने के लिए अब मेरी नेवबार

var homePageNavbar = new MyApp.Header.Default({ 
    title: 'Homepage' 
}); 

का उपयोग के चलाते हैं

और कल्पना हम इस उत्पादन

// My properties, all nicely inherited 
viewOptions: Array[5] //['children', 'titleBarChildren', 'secondaryBarChildren', 'title', 'backButtonTitle'] 
children: Array[0], 
titleBarChildren: Array[1], 
secondaryBarChildren: Array[0], 
title: "Homepage", 
backButtonTitle: "Terug" 

// Some stuff that backbone assigns 
$el: jQuery.fn.jQuery.init[1] 
cid: "view12" 
el: HTMLDivElement 
options: Object 
__proto__: ctor 

परिणाम मैं अंत में प्राप्त करने के लिए कोशिश कर रहा हूँ है कि मिलता है, यह हालांकि कुछ जादू है कि मेरे अनुभव से परे है की आवश्यकता है।

एक तरफ ध्यान दें, मैंने अपनी सभी कस्टम सामग्री के लिए "विकल्प" संपत्ति का उपयोग करने का प्रयास किया है, लेकिन समस्या यह है कि जब मैं एकाधिक दृश्य उदाहरण बनाते हैं, तो विकल्प एक दूसरे को "साझा"/संदर्भित करते हैं।

तो अब मुझे लगता है मैं "viewOptions" दृष्टिकोण के साथ और अधिक भाग्य होगा आशा करता हूं, और उसके बाद अधिभावी _configure method

अधिमानतः यह सब UI.Component में किया जाता है या यह बच्चों के लिए है। मैं नहीं चाहता कि इस लाइब्रेरी के उपयोगकर्ताओं को अपने हेडर डेफिनिशन (MyApp.Headers.Default = UI.Header.extend) में कुछ "बॉयलरप्लेट कोड" जोड़ने के लिए विकल्प या जो भी हो।

अब मुझे किसी भी तरह से सभी "निर्णायक" संयुक्त सभी प्रस्तावों को प्राप्त करना होगा। और मेरे पास बिल्कुल कोई सुराग नहीं है कि इसके बारे में कैसे जाना है। मैंने रीढ़ की हड्डी में दृश्यों के पीछे क्या चल रहा है, लेकिन मैं इसके चारों ओर अपने सिर को लपेट नहीं सकता हूं।

तो ऐसा करने पर युक्तियाँ/युक्तियां बहुत सराहना की जाती हैं, वैकल्पिक तरीकों या तरीकों से जो मेरी सटीक आवश्यकताओं से मेल नहीं खाती हैं, उनका स्वागत है।

संपादित करें 1

ऐसा लगता है कि मैं कुछ है कि काम करता है "की तरह", यहाँ यह क्या

जैसे मैं _configure विधि ओवरराइड, उदाहरण पर विकल्प जोड़ने के लिए दिखाई देता है, ध्यान दें this.getDefaultOptions() _.extend में पहला तर्क के रूप में

UI.Component = Backbone.View.extend({ 
    _configure: function(options) { 
    var viewOptions = this.viewOptions; 
    options = _.extend(this.getDefaultOptions ? this.getDefaultOptions() : {}, this.options || {}, options || {}); 
    for (var i = 0, l = viewOptions.length; i < l; i++) { 
     var attr = viewOptions[i]; 
     if (options[attr]) this[attr] = options[attr]; 
    } 
    this.options = options; 
    } 
}); 

मैं अपने सभी घटकों को यह नई विधि जोड़ा, और मेरे आधार वस्तु (UI.Component) में डाल नहीं था "साझा" गुण के बाद से मैं couln 'टी अच्छा खेलने के लिए मिलता है।

UI.Header = UI.Component.extend({ 

    viewOptions: ['children', 'backButtonTitle', 'title'], 

    getDefaultOptions: function() { 
    return { 
     children: [] 
    }; 
    }, 
}); 

अब, मैं कुछ इस तरह मेरी हैडर

MyApp.Headers.Default = UI.Header.extend({ 
    options: { 
    backButtonTitle: 'Terug', 
    titleBarChildren: [ 
     new UI.SegmentedController({ 
     children: [ 
      new UI.Button('Lame example') 
     ] 
     }) 
    ] 
    } 
}); 

परिभाषित करने के लिए उपयोग करते हैं मैं इसे जिस तरह से यह अब है रखने और देखें कि यह "समाधान" बचता होगा, और वापस रिपोर्ट करेंगे। आपको लगता है आप एक बेहतर जवाब है, यह पोस्ट करने के लिए hestitate नहीं है, तो =)

संपादित

यह मेरी नवीनतम दृष्टिकोण, jQuery के गहरे प्रति का उपयोग कर रहा है, यह allright काम करने के लिए

var UI = {}; 
var App = { 
    Headers: {} 
}; 

UI.Component = Backbone.View.extend({ 
    blockDefaults: { 
    children: [] 
    }, 

    initialize: function(options) { 
    var combinedDefaultsAndOptions = $.extend(true, {}, this.blockDefaults || {}, this.defaults || {}, this.options || {}, options || {}); 
    _.defaults(this, combinedDefaultsAndOptions); 
    } 
}); 

UI.Header = UI.Component.extend({ 
    defaults: { 
    backButton: null, 
    backButtonTitle: null, 
    secondaryBarChildren: [] 
    } 
}); 

App.Headers.Default = UI.Header.extend({ 
    options: { 
    backButtonTitle: "App back", 
    secondaryBarChildren: ["App child"] 
    } 
}); 

var header1 = new UI.Header({ 
    backButtonTitle: "Header 1 Back", 
    secondaryBarChildren: ["Header 1 child"] 
}); 

var header2 = new UI.Header({ 
    backButtonTitle: "Header 2 Back", 
    secondaryBarChildren: ["Header 2 child"] 
}); 

var header3 = new App.Headers.Default({ 
}); 

var header4 = new App.Headers.Default({ 
    backButtonTitle: "Overrided App Back" 
}); 

header1.secondaryBarChildren.push('a child for header 1'); 

console.log(header1, header2, header3, header4); 
लगता है

उत्तर

1

मुझे लगता है कि आप अपने उदाहरण के लिए प्रारंभिक फ़ंक्शन को ओवरराइड करना चाहते हैं लेकिन आपके पास बहुत कुछ चल रहा है इसलिए मुझे यकीन नहीं है; अगर यह बंद है तो मुझे माफ़ कर दो। और मैं बस सफाई कर सकता हूं जो मुझे लगता है कि आप एक और 'बैकबोन' शैली प्रणाली में करने की कोशिश कर रहे हैं। इस तरह अपने आधार घटक के साथ

प्रारंभ:

UI.Component = Backbone.View.extend({ 
    defaults : { 'children' : [] }, 
    initialize : function (options) { 
     _.defaults(options, this.defaults); 
     _.keys(this.defaults).forEach(function(key) { 
       this[key] = this.options[key]; 
     }.bind(this)); 
     Backbone.View.prototype.initialize.call(this, options); 
    }, 
    add: function(child) { 
     this.children.push(child); 
    } 
}); 

तो फिर तुम इस तरह से उन्हें एक समान तरीके से विस्तार करने के लिए जारी रख सकते हैं:

UI.Header = UI.Component.extend({ 
    defaults : { 
     'titleBarChildren' : [], 
     'secondaryBarChildren' : [], 
     'title' : '', 
     'backButtonTitle' : 'Back' 
    }, 
    initialize : function (options) { 
     _.defaults(options, this.defaults); 
     _.keys(this.defaults).forEach(function(key) { 
       this[key] = this.options[key]; 
     }.bind(this)); 
     UI.Component.prototype.initialize.call(this, options); 
    } 
}); 

यहाँ मैं क्या कोशिश कर रहा हूँ के टूटने है कोड में करें:

डिफ़ॉल्ट एक ऑब्जेक्ट बनाता है जो आपके सभी डिफ़ॉल्ट विशेषताओं को साफ़ करता है

defaults : { 'children' : [] }, 

प्रारंभ ओवरराइड आप देखना देखने से विकल्पों गुजर जारी रखने के लिए अनुमति देता है, लेकिन प्रत्येक घटक अपने defaults ऑब्जेक्ट का उपयोग करता अंतराल में भरने के लिए।

initialize : function (options) { 
     // merges your defaults in with the options passed 
     _.defaults(options, this.defaults); 
     // loop through your required defaults for this view 
     // assigning the attributes to the passed options 
     _.keys(this.defaults).forEach(function(key) { 
       this[key] = this.options[key]; 
     }.bind(this)); 
     // Finally pass all your options up the chain of inheritance 
     UI.Component.prototype.initialize.call(this, options); 
    }, 
+0

इस पर जाने के लिए धन्यवाद, मैं निश्चित रूप से इसके साथ खेलूँगा और रिपोर्ट करूंगा, क्या यह "घटकों" दोनों में प्रारंभिक विधि जोड़ने का एक कारण है? और, क्या यह सही है कि UI.Component प्रारंभिक विधि में स्वयं को कॉल करता है? (UI.Component.prototype.initialize.call (यह, विकल्प);) क्या इसका परिणाम अंतहीन पाश में नहीं होगा? – Vespakoen

+0

ओह, ठीक है। पहली दृश्य वस्तु में आप इसे प्रारंभिक विधि चलाने के लिए चाहते हैं, घटक नहीं। अच्छी पकड़, मैं इसे अद्यतन करने की कोशिश करूंगा। –

+0

इसके लिए धन्यवाद, और मुझे डिफ़ॉल्ट दिखाने के लिए धन्यवाद: {} विचार, यह एक असली आंख खोलने वाला है। चूंकि मुझे केवल विस्तार के 3 स्तर की आवश्यकता है, इसलिए मैं "ब्लॉकडिफॉल्ट" और सामान्य "डिफ़ॉल्ट" में निर्माण करता हूं, और इसके अलावा वे मेरे घटकों पर "विकल्प" सेट कर सकते हैं, और उदाहरण बनाते समय उन्हें ओवरराइड कर सकते हैं, मैं इसके साथ बहुत खुश हूं अब तक (मेरा नवीनतम संपादन देखें)। मैं उस पर एक और रात सो जाऊंगा और मैं देखूंगा कि कल मैं इसके बारे में क्या सोचता हूं =) – Vespakoen

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