2012-01-19 18 views
40
this.col = Backbone.Collection.extend({ 
    model: M, 
    comparator: function(item) { 
     return item.get("level"); 
    } 
    }); 

यह उपरोक्त कोड स्तर से आइटम प्रकार करता है। मैं स्तर से क्रमबद्ध करना चाहता हूं, फिर शीर्षक से। क्या मै वह कर सकता हूं? धन्यवाद।बैकबोन.जेएस संग्रह तुलनित्र कई क्षेत्रों द्वारा क्रमबद्ध करें?

+3

2012 की शुरुआत के बाद से सॉर्ट-स्टाइल तुलनाकर्ताओं के लिए समर्थन है। बस 2 तर्क स्वीकार करें और -1, 0 या 1 लौटें। Https: // github।com/documentcloud/backbone/commit/6b3ff7b0359510917d9ead8c8e16a7457eef05ef – geon

उत्तर

72

@ amchang87 के जवाब निश्चित रूप से काम करता है, लेकिन एक और है कि मैं काम बस sortable क्षेत्रों की एक सरणी लौटने पाया: अभी तक

मेरे पास एकाधिक ब्राउज़र में इस परीक्षण नहीं किया जैसा कि मैंने यह जे एस पर निर्भर करता है लगता है 'सरणी के क्रम में व्यवहार (उनकी सामग्री के आधार पर)। यह निश्चित रूप से वेबकिट में काम करता है।

+5

2012 की शुरुआत के बाद से सॉर्ट-स्टाइल तुलनाकर्ताओं के लिए समर्थन है। बस 2 तर्क स्वीकार करें और -1, 0 या 1 लौटें। Https://github.com/documentcloud/backbone/commit/6b3ff7b0359510917d9ead8c8e16a7457eef05ef – geon

+2

तो सीधे आगे, यह तकनीक है कॉफीस्क्रिप्ट में एक उदाहरण दिया गया है: https://gist.github.com/jhabdas/9822535 –

+5

ध्यान दें कि (कम से कम वेबकिट में) दोनों फ़ील्ड की तुलना तारों के रूप में की जाएगी। यदि आप संख्या क्रमबद्ध करने की कोशिश कर रहे हैं तो आप 1, 10, 2, 20, 200, आदि के साथ समाप्त होने जा रहे हैं। – RobW

1

मुख्य बात यह है कि बैकबोन एक आइटम के एक ही सापेक्ष मूल्य से दूसरे आइटम में टाइप करता है। इसलिए एक संग्रह में दो बार क्रमबद्ध करना संभव नहीं है लेकिन मैं इसे आजमाउंगा।

this.col = Backbone.Collection.extend({ 
    model: M, 
    comparator: function(item) { 
     // make sure this returns a string! 
     return item.get("level") + item.get("title"); 
    } 
}); 

क्या यह कर देगा "1Cool", "1title", "2newTitle" की तरह की एक स्ट्रिंग वापसी है ... जावास्क्रिप्ट संख्यात्मक चरित्र द्वारा तार पहले तो हर किरदार के बाद सॉर्ट चाहिए। लेकिन यह तब तक काम करेगा जब तक आपके स्तरों की संख्या बराबर न हो। आईई "001 शीर्षक" बनाम "200 टाइटल"। मुख्य विचार यह है कि आपको दो तुलनीय वस्तुओं का उत्पादन करने की आवश्यकता है, एक संख्या या स्ट्रिंग लाइन करें, जिसे एक दूसरे के साथ एक मानदंड के आधार पर तुलना की जा सकती है।

अन्य समाधान अंडरस्कोर उपयोग करने के लिए "GroupBy" करने के लिए अपने स्तर फिर "sortby" का उपयोग मैन्युअल रूप से प्रत्येक स्तर समूह सॉर्ट करने के लिए तो मैन्युअल रूप से इस नव निर्मित सरणी के साथ अंतर्निहित संग्रह की जगह होगी। जब भी संग्रह "परिवर्तन" करता है तो आप इसे करने के लिए शायद एक फ़ंक्शन सेट कर सकते हैं।

+0

यदि मैं 'groupby' विधि को समझ रहा हूं जो मेरे डेटा मॉडलिंग को गड़बड़ कर देगा? पहला समाधान थोडा अच्छा है, इसलिए इसके लिए धन्यवाद। – Harry

+0

यह सुनिश्चित नहीं है कि यह करने का सबसे अच्छा तरीका है। उदाहरण के लिए, यदि आपके पास 2 मॉडल थे: मॉडल 1-> स्तर: 1, शीर्षक: "1-चीज़"; मॉडल 2 -> स्तर: 10, शीर्षक: "-thing", तो आप उम्मीद करेंगे कि इसे मॉडल 1, मॉडल 2 को सॉर्ट किया जाएगा - लेकिन उस तुलनित्र द्वारा, यह स्ट्रिंग "11-चीज़" और "10-चीज़" की तुलना करेगा, तो ऐसा होगा गलत क्रम में क्रमबद्ध किया जा सकता है –

+0

यह एक सरणी द्वारा क्रमबद्ध करने की कोशिश करने के लिए कार्यात्मक समान है, एक तर्क से '[1,' x ']' वापस लौटने वाला तुलनित्र फ़ंक्शन स्ट्रिंग '1, x" की तुलना करने के बजाय क्रमबद्ध करेगा अवयव। –

7

स्ट्रिंग कॉन्सटेनेशन आरोही क्रम में एकाधिक फ़ील्ड को सॉर्ट करते समय ठीक काम करता है, लेकिन यह मेरे लिए काम नहीं करता क्योंकि 1) मुझे प्रति फ़ील्ड एसी/desc का समर्थन करना था और 2) कुछ फ़ील्ड संख्या फ़ील्ड थे (यानी, मुझे 10 चाहिए अगर यह चढ़ाई हो तो 2 के बाद आना)। तो, नीचे एक तुलनित्र समारोह मैं इस्तेमाल किया था और मेरी जरूरतों के लिए ठीक काम किया। यह मान लिया गया है रीढ़ की हड्डी संग्रह एक चर 'sortConfig' है, जो क्षेत्र का नाम और क्रम दिशा सॉर्ट साथ JSON ऑब्जेक्ट की एक सरणी है के साथ सौंपा गया है। उदाहरण के लिए,

{ 
    "sort" : [ 
     { 
      "field": "strField", 
      "order": "asc" 
     }, 
     { 
      "field": "numField", 
      "order": "desc" 
     }, 
     ... 
    ] 
} 
संग्रह करने के लिए 'sortConfig' के रूप में सौंपा ऊपर JSON ऑब्जेक्ट के साथ

, नीचे समारोह बैकबोन तरह strField से आरोही क्रम में पहले तो तरह numField अवरोही क्रम, आदि तो में कर देगा, कोई सॉर्ट क्रम निर्दिष्ट किया जाता है, यह डिफ़ॉल्ट रूप से आरोही क्रमबद्ध करता है। यदि आप उतरते और कुछ क्रम में क्रमबद्ध करने की जरूरत है

multiFieldComparator: function(one, another) { 
    // 'this' here is Backbone Collection 
    if (this.sortConfig) { 
     for (var i = 0; i < this.sortConfig.length; i++) { 
      if (one.get(this.sortConfig[i].field) > another.get(this.sortConfig[i].field)) { 
       return ("desc" != this.sortConfig[i].order) ? 1 : -1; 
      } else if (one.get(this.sortConfig[i].field) == another.get(this.sortConfig[i].field)) { 
       // do nothing but let the loop move further for next layer comparison 
      } else { 
       return ("desc" != this.sortConfig[i].order) ? -1 : 1; 
      } 
     } 
    } 
    // if we exited out of loop without prematurely returning, the 2 items being 
    // compared are identical in terms of sortConfig, so return 0 
    // Or, if it didn't get into the if block due to no 'sortConfig', return 0 
    // and let the original order not change. 
    return 0; 
} 
2

एक सरणी रिटर्निंग संगत नहीं है ...

मैं जो प्रासंगिक तुलना पूर्णांक बैकबोन तुलनाकारी वापस करने के लिए वापस जाने के लिए इस्तेमाल किया जा सकता कार्यों का एक छोटा सा सेट बनाया समारोह:

backbone-collection-multisort

0

"प्रेरित" Hyong जवाब में।

यह भी है, अगर वहाँ है कि वस्तु एक समारोह है कि एक विशेषता होती है इससे पहले कि आप डेटा को बदलने यह तुलना कर सकते हैं, valueTransforms एक वस्तु है, यह प्रयोग किया जाएगा।

/* 
    * @param {Object} sortOrders ie: 
    * { 
    *  "description": "asc", 
    *  "duedate": "desc", 
    * } 
    * @param {Object} valueTransforms 
    */ 
    setMultiFieldComparator: function(sortOrders, valueTransforms) { 
     var newSortOrders = {}, added = 0; 
     _.each(sortOrders, function(sortOrder, sortField) { 
      if (["asc", "desc"].indexOf(sortOrder) !== -1) { 
       newSortOrders[sortField] = sortOrder; 
       added += 1; 
      } 
     }); 
     if (added) { 
      this.comparator = this._multiFieldComparator 
       .bind(this, newSortOrders, valueTransforms || this.model.prototype.valueTransforms || {}); 
     } else { 
      this.comparator = null; 
     } 
    }, 

    _multiFieldComparator: function(sortOrders, valueTransforms, one, another) { 
     var retVal = 0; 
     if (sortOrders) { 
      _.every(sortOrders, function(sortOrder, sortField) { 
       var oneValue = one.get(sortField), 
        anotherValue = another.get(sortField); 
       if (valueTransforms[sortField] instanceof Function) { 
        oneValue = valueTransforms[sortField](oneValue); 
        anotherValue = valueTransforms[sortField](anotherValue); 
       } 
       if (oneValue > anotherValue) { 
        retVal = ("desc" !== sortOrder) ? 1 : -1; 
       } else if (oneValue < anotherValue) { 
        retVal = ("desc" !== sortOrder) ? -1 : 1; 
       } else { 
        //continue 
        return true; 
       } 
      }); 
     } 
     return retVal; 
    }, 
संबंधित मुद्दे