2012-10-26 13 views
14

कुछ सरल होना चाहिए जो मैं यहां याद कर रहा हूं।रीबोन/अंडरस्कोर श्रृंखला विधि जहां विधि

http://jsfiddle.net/v9mdZ/

मैं सिर्फ रीढ़ और अंडरस्कोर/loDash सीख रहा हूँ और chain से परिचित होने की कोशिश कर रहा हूँ।

मैं निम्नलिखित कोड है, जो रूप में काम करता उम्मीद है

var ids = _.pluck(collection.where({'is_checked':true}), 'id'); 

मैं बहुत तरह chain का उपयोग कर इस refactor का प्रयास किया,:

var ids = collection.chain().where({'is_checked':true}).pluck('id').value(); 

क्यों नहीं पुनर्संशोधित कोड काम करता है? क्या मैं chain गलत उपयोग कर रहा हूँ?

समाधान (विवरण नीचे)

chain साथ where प्रयोग न करें।

उत्तर

18

संग्रह में some Underscore methods का विलय थोड़ा अपूर्ण है। जब आप collection.some_mixed_in_underscore_method() कहते हैं, तो संग्रह आपकी पीठ के पीछे बैकबोन सामग्री में से कुछ को अनचाहे करता है ताकि अंडरस्कोर विधि संग्रह के मॉडल के अंदर विशेषताओं पर लागू हो; यह एक तरह से इस तरह काम करता है:

var ary = _(this.models).map(function(m) { return m.attributes }); 
return _(ary).some_mixed_in_underscore_method(); 

लेकिन collection.chain() उस तरह काम नहीं करता है, chain सिर्फ संग्रह का models लपेटता सीधे इसलिए यदि आप ऐसा करते हैं:

console.log(collection.chain()); 

आप देखेंगे chain है कि आपको एक वस्तु दे रही है जो मॉडलों की एक सरणी लपेटती है। आपके मॉडल में is_checked प्रॉपर्टी नहीं होगी (यानी model.is_checked नहीं है), उनके पास is_checked विशेषताएँ होंगी (यानी model.get('is_checked') और model.attributes.is_checked होगा)।

अब हम देख सकते हैं जहां सब कुछ गलत हो जाता है:

collection.chain().where({'is_checked':true}) 

मॉडल is_checked गुण नहीं है। विशेष रूप से, ऐसे कोई मॉडल नहीं होंगे जहां is_checkedtrue है और where के बाद सब कुछ खाली सरणी के साथ काम कर रहा है।

अब हम जानते हैं कि चीजें किनारे पर जाती हैं, हम इसे कैसे ठीक करते हैं? ठीक है, आप filter बजाय where इस्तेमाल कर सकते हैं ताकि आप आसानी से मॉडल खोल कर सकते हैं:

collection.chain() 
      .filter(function(m) { return m.get('is_checked') }) 
      .pluck('id') 
      .value(); 

लेकिन, अपने मॉडल id की जरूरत नहीं है है अभी तक आप id रों के साथ उन्हें का निर्माण नहीं किया के रूप में और आप हेवन ' टी id एस प्राप्त करने के लिए किसी सर्वर से बात की गई है, इसलिए आपको undefined के पीछे की सरणी मिल जाएगी। आप कुछ id रों जोड़ते हैं:

var collection = new App.OptionCollection([ 
    {id: 1, 'is_checked': true}, 
    {id: 2, 'is_checked': true}, 
    {id: 3, 'is_checked': false} 
]); 

तो आप [1,2] कि आप देख रहे हैं मिल जाएगा।

डेमो: http://jsfiddle.net/ambiguous/kRmaD/

+0

बहुत बढ़िया विवरण। धन्यवाद! मेरे वास्तविक वातावरण में, संग्रह सर्वर से प्राप्त किया जाता है, इसलिए उनके पास आईडी हैं। – Bart

+0

'प्लक' में अधिकांश विशेषताओं के लिए एक ही समस्या होगी क्योंकि यह 'model.get()' को कॉल नहीं करती है बल्कि इसके बजाय मॉडल के विशेषताओं पर सीधे दिखती है। 'id' एक विशेष विशेषता है जिसे ऑब्जेक्ट पर परिभाषित किया गया है, इसलिए यह काम करेगा लेकिन अन्य विशेषताएँ, जैसे 'is_checked'' अपरिभाषित 'वापस आ जाएगी। – Spig

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