2012-07-16 11 views
11

Mam kolekcję kręgosłupa, która jest renderowana w tabeli. Chciałbym dokonać sortowania tabeli na podstawie pewnych atrybutów kolekcji, takich jak "task_status", "task_group". Czytałem dokumentację szkieletową o collection.comparator, nd collection.sort. Jak mogę to zrobić?sortuj kolekcję szkieletową na podstawie atrybutów modelu

Odpowiedz

29

Funkcja comparator służy do porównywania dwóch modeli w kolekcji i może je porównywać w dowolny (spójny) sposób, jaki chce. W szczególności, może wybrać, który model przypisują używać tak można mieć coś takiego w swojej kolekcji:

initialize: function() { 
    this.sort_key = 'id'; 
}, 
comparator: function(a, b) { 
    // Assuming that the sort_key values can be compared with '>' and '<', 
    // modifying this to account for extra processing on the sort_key model 
    // attributes is fairly straight forward. 
    a = a.get(this.sort_key); 
    b = b.get(this.sort_key); 
    return a > b ? 1 
     : a < b ? -1 
     :   0; 
}  

a następnie wystarczy kilka metod na zbiorach zmienić sort_key i nazywają sort:

sort_by_thing: function() { 
    this.sort_key = 'thing'; 
    this.sort(); 
} 

W starszych kręgach, wywołanie sort wyzwoli zdarzenie "reset", podczas gdy nowsze wersje wyzwolą zdarzenie "sort". Na pokrycie obu przypadkach można słuchać obu imprez i re-render:

// in the view... 
initialize: function() { 
    this.collection.on('reset sort', this.render, this); 
} 

Demo: http://jsfiddle.net/ambiguous/7y9CC/

Można również użyć listenTo zamiast on aby pomóc uniknąć zombie:

initialize: function() { 
    this.listenTo(this.collection, 'reset sort', this.render); 
} 

Demo: http://jsfiddle.net/ambiguous/nG6EJ/

+0

mogę wykorzystać ten wzór w sytuacji, w której pola sortowania są ciągi – MrFoh

+0

@MrFoh: Tak, '>' i '<' praca w łańcuchach atrybut 's' w wersji demonstracyjnej jest łańcuchem znaków. –

+1

Uwaga: ten przykład już nie działa, ponieważ Backbone nie uruchamia już zdarzenia resetowania podczas sortowania. Wystrzeliwuje zdarzenie sortowania. –

20

@ Odpowiedź "mu-is-too-short" jest dobra, z wyjątkiem prostszego sposobu porównania pola wartości:

Najprostszym sposobem posortowania kolekcji na podstawie pola jest udostępnienie funkcji porównującej, która zwraca wartość tego pola, według którego chcesz sortować. Ten rodzaj komparatora powoduje, że Backbone wywołuje funkcję sortBy, zamiast sort, która następnie wykonuje to skomplikowane porównanie na własną rękę i nie musisz się martwić o logikę.

W gruncie rzeczy nie trzeba udostępniać złożonej funkcji porównawczej, chyba że istnieje bardziej zaawansowana potrzeba określenia zamówienia.

var myCollection = Backbone.Collection.extend({ 
    sort_key: 'id', // default sort key 
    comparator: function(item) { 
     return item.get(this.sort_key); 
    }, 
    sortByField: function(fieldName) { 
     this.sort_key = fieldName; 
     this.sort(); 
    } 
}); 

Po tym można po prostu zadzwonić kolekcji za sortByField -function sznurkiem, który reprezentuje klawisz który chcesz sortować. Na przykład:

collection.sortByField('name'); 

Modified @ my-to-too-short demo: http://jsfiddle.net/NTez2/39/

+1

Uwaga: ten przykład już nie działa, ponieważ kręgosłup nie uruchamia już zdarzenia resetowania podczas sortowania. Wystrzeliwuje zdarzenie sortowania. –

+1

Dzięki za heads up! Zaktualizowałem przykład, aby uwzględnić tę zmianę: http://jsfiddle.net/NTez2/39/ – jylauril

+1

Duży problem z pojedynczym komparatorem argumentów (i '_.sortBy') polega na tym, że nie można przełączać pomiędzy rosnącym i malejącym porządkiem na sznurku w dowolny rozsądny sposób. Zniżanie liczb jest łatwe, ponieważ możesz negować liczby, ale negowanie ciągu znaków nie jest takie łatwe. Nie można również sortować według kilku kluczy, bez zacierania ich w jeden ciąg i który dba o prawidłowe wykonanie. –

3

@ odpowiedź jylauril pomaga się ogromnie, ale potrzebne do modyfikacji demo (prawdopodobnie nieznaczne zmiany w szkielecie, ponieważ została wysłana ?)

Wygląda na to, że trzeba wyzwolić render po posortowaniu.

$('#by-s').click(function() { 
    c.sortByField('s'); 
    v.render(); 
}); 

Updated @ demo My-is-too-short za: http://jsfiddle.net/NTez2/13/

Powiązane problemy