2012-04-17 11 views
15

मैंने संग्रह से अगले या पिछले मॉडल को प्राप्त करने के कुछ अलग-अलग तरीकों को देखा है, लेकिन यह सोच रहा था कि अगर कोई इसे लागू करने का निर्णय लेता है तो कोई सलाह दे सकता है। मेरा संग्रह आदेश दिया गया है, लेकिन जिस आईडी पर मैं सॉर्ट कर रहा हूं वह अनुक्रमिक होने की गारंटी नहीं है। यह केवल अद्वितीय होने की गारंटी है। मान लें कि छोटे आईडी संग्रह में "पुरानी" प्रविष्टियां हैं और बड़ी आईडी "नई" हैं।संग्रह से अगले और पिछले मॉडल को प्राप्त करना

MyCollection = Backbone.Collection.extend({ 
    model: MyModel, 
    initialize:function(){ 
    this.getElement = this._getElement(0); 
    }, 
    comparator: function(model) { 
    return model.get("id"); 
    }, 
    _getElement: function (index){ 
    var self = this; 
    return function (what){ 
    if (what === "next"){ 
     if (index+1 >= self.length) return null; 
     return self.at(++index); 
    } 
    if (what === "prev"){ 
     if (index-1 < 0) return null; 
     return self.at(--index); 
    } 
    // what doesn't equal anything useful 
    return null; 
    }; 
    } 
}); 

getElement का उपयोग कर, मैं चीजों को getElement ("अगले") और getElement ("पिछला") की तरह मेरे संग्रह में अगले या पिछले मॉडल के लिए पूछने के लिए करते हैं। GetElement से वापस क्या किया जाता है वास्तविक मॉडल है, सूचकांक नहीं। मैं collection.indexOf के बारे में जानता हूं, लेकिन मैं पहले से मॉडल शुरू करने के बिना संग्रह के माध्यम से लूप करने का एक तरीका चाहता था। क्या यह कार्यान्वयन कठिन होने की आवश्यकता है?

उत्तर

23

मैं ऐसा कुछ करूंगा। ध्यान रखें कि वर्तमान में कोई त्रुटि प्रबंधन नहीं है, इसलिए यदि आप वर्तमान में संग्रह में पहले मॉडल में हैं और पिछले प्राप्त करने का प्रयास करते हैं तो आपको शायद एक त्रुटि मिल जाएगी।

MyCollection = Backbone.Collection.extend({ 
    model: MyModel, 
    initialize:function(){ 
    this.bindAll(this); 
    this.setElement(this.at(0)); 
    }, 
    comparator: function(model) { 
    return model.get("id"); 
    }, 
    getElement: function() { 
    return this.currentElement; 
    }, 
    setElement: function(model) { 
    this.currentElement = model; 
    }, 
    next: function(){ 
    this.setElement(this.at(this.indexOf(this.getElement()) + 1)); 
    return this; 
    }, 
    prev: function() { 
    this.setElement(this.at(this.indexOf(this.getElement()) - 1)); 
    return this; 
    } 
}); 

अगले मॉडल collection.next() पर प्रगति के लिए। अगले मॉडल पर प्रगति करने और इसे var m = collection.next().getElement();

थोड़ा बेहतर समझाएं कि अगली/पिछली बार कैसे काम करती है।

// The current model 
this.getElement(); 
// Index of the current model in the collection 
this.indexOf(this.getElement()) 
// Get the model either one before or one after where the current model is in the collection 
this.at(this.indexOf(this.getElement()) + 1) 
// Set the new model as the current model 
this.setElement(this.at(this.indexOf(this.getElement()) + 1)); 
+0

मुझे आपके कुछ विचार पसंद हैं, विशेष रूप से प्रारंभिक विधि में this.at() का उपयोग करना। यद्यपि आपका कोड हालांकि काफी लंबा है। यदि कोई और कुछ बेहतर और/या अधिक संक्षेप में सुझाव नहीं देता है, तो आपको हरे रंग की जांच मिल जाएगी :-) मेरी विधि कम है और जब आप किसी भी अंत तक पहुंच जाते हैं तो नल लौटकर संग्रह के अंत से गिरने से रोकता है। –

+0

आप 'सेट/getElement' फ़ंक्शंस को हटाकर और' currentElement' मान को सीधे एक्सेस करके इसे छोटा कर सकते हैं। – abraham

+4

यदि v0.9 + का उपयोग करना है तो आपको यह होना होगा .setElement (this.at (0)); जो वर्तमान में संग्रह बनाने के बाद बुलाए जाने वाले प्रारंभिक कार्य में है। ऐसा इसलिए है क्योंकि कलेक्शन मॉडल बनाने से पहले प्रारंभिक कहलाता है। उदाहरण: var myCollection = नया MyCollection (डेटा); myCollection.setElement (this.at (0)); –

6

मैंने यह थोड़ा अलग तरीके से किया है कि मैं संग्रह के बजाय मॉडल में विधियों को जोड़ रहा हूं। इस तरह, मैं किसी भी मॉडल को पकड़ सकता हूं, और अनुक्रम में अगला प्राप्त कर सकता हूं।

next: function() { 
    if (this.collection) { 
     return this.collection.at(this.collection.indexOf(this) + 1); 
    } 
}, 
prev: function() { 
    if (this.collection) { 
     return this.collection.at(this.collection.indexOf(this) - 1); 
    } 
}, 
+0

जबकि मुझे दृष्टिकोण पसंद है, इस अभ्यास में कुछ समस्याएं हैं। 1. आपको अपने मॉडल में एक कस्टम "संग्रह" संपत्ति जोड़ने की आवश्यकता है जो उस विशिष्ट संग्रह का संदर्भ देता है जिसके साथ आप काम करना चाहते हैं। यह मानता है कि आपका मॉडल केवल एक संग्रह का सदस्य है, जो मामला नहीं हो सकता है। बैकबोन का आर्किटेक्चर ढीले युग्मन और लचीलापन सुनिश्चित करने के लिए देखे गए संग्रह और विचारों के बारे में बोलने के लिए मॉडल को "अंधेरे में" रखता है। 2. यह तरीका त्रुटियों को फेंक देगा अगर यह.collection.indexOf (यह) <= 0 || this.collection.indexOf (यह)> = संग्रह.size()। – 1nfiniti

+0

@mikeyUX मैं मानता हूं कि केवल एक संग्रह से संबंधित होने में सक्षम होना प्रतिबंधित हो सकता है, यह बैकबोन तरीका है। मैं व्यक्तिगत रूप से सोचता हूं कि बैकबोन में कुछ सूची कार्यान्वयन होना चाहिए जिसका उपयोग केवल मॉडल 'संग्रह' के लिए किया जाता है लेकिन सभी सर्वर-साइड सामान के बिना, ताकि आप कई संग्रहों की तरह चीजें आसानी से कर सकें। इसके अलावा, आप आसानी से इसे चारों ओर स्वैप कर सकते हैं, इसलिए यह संग्रह पर एक विधि है जो एक मॉडल को तर्क के रूप में लेता है: '' 'collection.next (मॉडल);' '' अंत में, इससे त्रुटियों में कोई त्रुटि नहीं होती है आपके द्वारा सुझाए गए परिदृश्य - यह अनिर्धारित लौटाता है, जिसकी अपेक्षा की जाती है! – Tom

2

कुछ हद तक एक अधिक सामान्य समाधान के साथ इस पुराने धागे Bumping:

सामग्री Collection.prototype में जोड़ने के लिए

current: null, 

initialize: function(){ 
    this.setCurrent(0); 
    // whatever else you want to do here... 
}, 

setCurrent: function(index){ 
    // ensure the requested index exists 
    if (index > -1 && index < this.size()) 
     this.current = this.at(index); 
    else 
     // handle error... 
}, 

// unnecessary, but if you want sugar... 
prev: function() { 
    this.setCurrent(this.at(this.current) -1); 
}, 
next: function() { 
    this.setCurrent(this.at(this.current) +1); 
} 

आप तो चीनी तरीकों का उपयोग कर सकते हैं पिछला पाने के लिए/अगले मॉडल जैसे ...

collection.prev(); 
collection.next(); 
0

मेरा बैकबो ne SelectableCollection class:

Backbone.Collection.extend({ 
    selectNext: function() { 
     if(this.cursor < this.length - 1) { 
      this.cursor++; 
      this.selected = this.at(this.cursor); 
      this.trigger('selected', this.selected); 
     } 
    }, 

    selectPrevious: function() { 
     if(this.cursor > 0) { 
      this.cursor--; 
      this.selected = this.at(this.cursor); 
      this.trigger('selected', this.selected); 
     } 
    }, 
    selectById: function (id) { 
     this.selected = this.get(id); 
     this.cursor = this.indexOf(this.selected); 
     this.trigger('selected', this.selected); 
    }, 
    unselect: function() { 
     this.cursor = null; 
     this.selected = null; 
     this.trigger('selected', null); 
    } 
}); 
संबंधित मुद्दे