3 Stimmen

Sortieren von Backbone-Sammlungen mit mehreren Attributen

Ich versuche, eine Sammlung von Modellen nach einem Erstellungsdatum oder einer Priorität zu sortieren, die von einem Benutzer ausgewählt werden können.

Die Priorität kann entweder in absteigender oder aufsteigender Reihenfolge gewählt werden, wobei die Modelle dann weiter nach Erstellungsdatum in absteigender Reihenfolge geordnet werden.

Das Erstellungsdatum kann auch in absteigender oder aufsteigender Reihenfolge ausgewählt werden, ohne weitere Unterordnung.

Im Folgenden finden Sie den Code, den ich bisher habe:

comparator: function(task) {
  var sorter = task.get(root.sortAttr);
  var subSorter = String.fromCharCode.apply(String,
    _.map(task.get("created_at").split(""), function (c) {
      return 0xffff - c.charCodeAt();
    })
  );

  if(!root.sortAscending) {
    console.log("desc");
    return -sorter + ", " + subSorter;
  }
  else {
    console.log("asc");
    return sorter + ", " + subSorter;
  }
}

Dieser Code funktioniert sowohl bei aufsteigender als auch bei absteigender Reihenfolge des Erstellungsdatums, zeigt die Prioritäten aber immer nur in absteigender Reihenfolge an. Kann mir jemand sagen, warum dies der Fall ist und was ich tun kann, um das zu beheben?

2voto

Gabriel Gartz Punkte 2730

Ok, nehmen wir an, Sie haben ein Attribut priority in Ihrem Modell.

Die Lösung dafür ist einfach:

sortOrder: 'asc',
comparator: function (item) {
  var timestamp = Date.parse(item.get('created_at')) * 1000;
  timestamp += item.get('priority');

  if (this.sortOrder === 'asc') {
    return timestamp;
  }

  return -timestamp;
}

Eine anspruchsvollere Lösung:

sortBy: {'created_at': 'asc', 'priority': 'desc'},
comparator: function (item) {
  var result = 0;
  for (var field in this.sortBy) {
      if (field === 'created_at') {
          result += (this.sortBy[field] === 'asc')
                 ? Date.parse(item.get('created_at')) * 1000
                 : -Date.parse(item.get('created_at')) * 1000;
      }

      if (field === 'priority') {
          result += (this.sortBy[field] === 'asc')
                 ? item.get(field)) * 1000
                 : -item.get(field)) * 1000;
      }
  }

  return result;
}

Sie können die sortBy um mit anderen Feldern zu arbeiten, parsen Sie es einfach in int. Achtung, wird fehlschlagen, wenn die Zahl > wird. Number.MAX_VALUE oder < Number.MIN_VALUE .

Sie können eine toInt() Methode für Ihre Felder, und verwenden Sie alles ohne das if innerhalb der Objektschleife.

result += (this.sortBy[field] === 'asc')
        ? item.get(field).toInt() * 1000
        : -item.get(field).toInt() * 1000;

1voto

mmilo Punkte 41

Am Ende verwendete ich einen rein stringbasierten Ansatz, der das gewünschte Ergebnis lieferte und mehr Flexibilität in Bezug auf die Unterstützung stringbasierter Sortierattribute bietet.

this.tasks.comparator = function(task) {
  var priority = (task.get("priority_id")).toString();
  var timestamp = task.get("created_at");

  if (!sortAscending) {
    if (sortAttribute == "created_at") return negateString(timestamp);
    if (sortAttribute == "priority_id") return negateString(negateString(priority) + "-" + negateString(timestamp));
  }
  else {
    if (sortAttribute == "created_at") return timestamp;
    if (sortAttribute == "priority_id") return negateString(priority) + "-" + timestamp;
  }
}

this.tasks.sort();

Die Funktion "negate string" ist dieselbe, die auch in aquí und im Folgenden wie folgt wiedergegeben:

var negateString = function(s) {
  s = s.toLowerCase();
  s = s.split("");
  s = _.map(s, function(letter) { 
    return String.fromCharCode(-(letter.charCodeAt(0)));
  });

  return s.join("");
};

1voto

David Morrow Punkte 8043

Backbone nimmt nun zwei Modelle an, die Sie vergleichen können. Fügen Sie einfach den zweiten Parameter zur Comparator-Funktion hinzu. Ich bin mir nicht sicher, warum die Dokumente nicht aktualisiert wurden.

comparator: function (model, model2) {
  return (model1.get('some_attribute') > model2.get('some_attribute')) ? -1 : 1;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X