2013-08-21 6 views
6

मैं एक बैकबोन जेएस एप्लिकेशन बना रहा हूं जिसमें विरासत और जावास्क्रिप्ट कीवर्ड का उदाहरण शामिल है।उदाहरण का कीवर्ड बैकबोन जेएस मॉडल के साथ क्यों काम नहीं करता है?

मैं निम्नलिखित कोड है:

app.Sport = Backbone.Model.extend 
({ 
    defaults: 
    { 
     id: 0, 
     title: 'Running' 
    } 
}); 
इसके अलावा कोड में

, मैं लिखकर नया खेल का दृष्टांत:

var newSport = new app.Sport(); 

मैं मुद्दों के बिना इस नव निर्मित उदाहरण में हेरफेर कर सकते हैं।

लेकिन, एक लेकिन क्योंकि, instanceof कीवर्ड हमेशा अवास्तविक लौटाते जब मेरे उदाहरण के प्रकार के लिए पूछ:

console.log ('is newSport a Sport instance ? ' + newSport instanceof app.Sport); 

हमेशा गलत प्रदर्शित करते हैं। क्यूं कर ?

नोट: मैंने अपने प्रश्न में विरासत का उल्लेख नहीं किया है, क्योंकि यह ओओपी के सरल रूप (बेस क्लास का एक उदाहरण, और इसके बाद के प्रकार के लिए पूछने) के साथ भी काम नहीं करता है।

मेरा प्रारंभिक उद्देश्य खेल के प्रकार (उदाहरण के लिए कीवर्ड का उपयोग) के आधार पर विशिष्ट कार्रवाई को ट्रिगर करना है;

app.CoolSport = app.Sport.extend ({ ... }); 
app.ExtremeSport = app.Sport.extend ({ ... }); 

संपादित: यह एक शांत एक, या एक चरम एक हो सकता है मैं इस मुद्दे को अलग किया। यह कीवर्ड या मॉडल I घोषित उदाहरण से जुड़ा हुआ नहीं है। इसके बजाय, मैं एक बैकबोन संग्रह तैयार करता हूं, और इसे कुछ अलग तरह के खेल में धक्का देता हूं। यहां टेस्ट कोड है: (Fiddle)

var app = {}; 


app.Sport = Backbone.Model.extend 
({ 
    defaults: 
    { 
     id: 0, 
     title: 'Running' 
    } 
}); 


app.CoolSport = app.Sport.extend 
({ 
    defaults: 
    { 
     uselessAttr:'I am a Cool Sport !' 
    } 
}); 



app.SportList = Backbone.Collection.extend 
({ 
    model: app.Sport 

}); 


var coolSport1 = new app.CoolSport(); 

console.log ('is coolSport1 a Sport instance ? ' , coolSport1 instanceof app.Sport); 

console.log ('is coolSport1 a CoolSport instance ? ' , coolSport1 instanceof app.CoolSport); 

console.log ('is coolSport1 a CoolSport instance (wrong operand in console) ? ' + coolSport1 instanceof app.CoolSport); 


var sportList = new app.SportList(); 
sportList.push (coolSport1.toJSON()); 


sportList.each (function (sport) 
{ 
    if (sport instanceof app.CoolSport) 
    { 
     console.log ("sport is an instance of Cool Sport ! Yeah !" , sport instanceof app.CoolSport) ; 
    }      
    else 
    { 
     console.log ("Not a CoolSport instance.."); 
    } 
}); 

और अनुमान लगाएं क्या? मेरा कूलस्पोर्ट उदाहरण ... कूलस्पोर्ट उदाहरण नहीं है। मुझे लगता है कि बैकबोन स्पोर्टलिस्ट संग्रह की शुरुआत इस मुद्दे पर है।

कोई विचार?

+0

काम करने के लिए लगता है http://jsfiddle.net/nikoshr/dX7Nz/ – nikoshr

+1

मैं आपकी समस्या को पुन: पेश करने के लिए एक पहेली हूं, लेकिन मेरे परीक्षणों से पता चलता है कि यह अपेक्षा के अनुसार काम करना चाहिए। रीढ़ की हड्डी/अंडरस्कोर का कौन सा संस्करण आप पर हैं? (fiddle: http://jsfiddle.net/HHS8u/) – jakee

+1

कंसोल.लॉग लिखने का प्रयास करें ('नया स्पोर्ट इंस्टेंस है?', (नयास्पोर्ट उदाहरण ऐप .पोर्ट)); - आपको उदाहरण मिलता है '' नया स्पोर्ट इंस्टॉलेशन है? + newSport' - यह एक स्ट्रिंग होगा – Sergey

उत्तर

2

मैं समाधान :-)

मैंने टिप्पणी पाया नीचे कोड:

var coolSport1 = new app.CoolSport(); 

// Of course it is 
console.log ('is coolSport1 a Sport instance ? ' , coolSport1 instanceof app.Sport); 

console.log ('is coolSport1 a CoolSport instance ? ' , coolSport1 instanceof app.CoolSport); 


var sportList = new app.SportList(); 

// Here is the tricky part : we push the JSON representation of our CoolSport instance 
sportList.push (coolSport1.toJSON()); 


// Backbone does not know anymore the subtype of our instance, as it has been JSON stringified juste before. 
sportList.each (function (sport) 
{ 
    if (sport instanceof app.CoolSport) 
    { 
     console.log ("sport is an instance of Cool Sport ! Yeah !" , sport instanceof app.CoolSport) ; 
    }      
    else 
    { 
     console.log ("Not a CoolSport instance.."); 
    } 
}); 

बैकबोन प्रलेखन इस व्यवहार के लिए एक तंत्र प्रदान करता:

var Library = Backbone.Collection.extend({ 

    model: function(attrs, options) { 
    if (condition) { 
     return new PublicDocument(attrs, options); 
    } else { 
     return new PrivateDocument(attrs, options); 
    } 
    } 

}); 

यह संग्रह बताता है कि कैसे एक JSON प्रतिनिधित्व कार्रवाई करने के लिए सूची में एक सही उप प्रकार उदाहरण जोड़ने के लिए,। इसलिए, कोड को छेड़छाड़ करते समय कूलस्पोर्ट जोड़ने के लिए, किसी को केवल स्पोर्टलिस्ट संग्रह में मॉडल फ़ंक्शन जोड़ने की आवश्यकता होती है, और यदि 'uselessAttr' (मेरे प्रश्न में कोड देखें) में एक नया कूलस्पोर्ट लौटाता है।

मैंने एक अलग तरीका लिया, और संग्रह के ऐड() विधि के माध्यम से सीधे कूलस्पोर्ट आवृत्ति पास की, इस प्रकार इसके उप प्रकार को संरक्षित किया।

मदद के लिए धन्यवाद सब लोग, और आशा है कि मेरा उत्तर :-)

5

कृपया, क्या नहीं इस:

console.log ('is newSport a Sport instance ? ' + newSport instanceof app.Sport); 

यह सही कार्य करें:

console.log ('is newSport a Sport instance ? ' + (newSport instanceof app.Sport)); 

या

console.log ('is newSport a Sport instance ? ', newSport instanceof app.Sport); 
+2

मैं इसे कभी भी खराब तरीके से नहीं करूंगा। इस गलती को इंगित करने के लिए धन्यवाद। कृपया मेरा अद्यतन प्रश्न देखें, क्योंकि यह मेरे पास असली मुद्दा बताता है। – jeromedt

1

आप के रूप में अपने संग्रह में मॉडल को परिभाषित कर रहे दूसरों की मदद करेगा 'app.Sport'

इसलिए जब आप coolSport1.toJSON (बढ़ा रहे हैं), इसे ऐप का उपयोग करके शुरू किया जाएगा .पोर्ट मॉडल

यही कारण है कि यह कूलस्पोर्ट उदाहरण नहीं बल्कि इसके बजाय एक खेल उदाहरण है।

+0

मुझे आपके सामने कुछ मिनट मिलते हैं (नीचे मेरा जवाब देखें), और वास्तव में यह सही समाधान था। और खुशी है कि अगर मैं इसे अपने आप नहीं मिला तो आप वहां थे ;-) – jeromedt

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