2012-09-22 7 views
8

Ich würde gerne in der Lage sein, eine ArrayController zu sortieren, deren Inhalt stammt aus einer Glutendaten Abfrage. Leider scheint das sortProperty Mixin in diesem Fall nicht zu funktionieren.Sortieren eines ArrayController von Ember-Daten über sortProperty Mixin

Ich möchte in der Lage sein, Folgendes zu tun:

App = Ember.Application.create(); 
App.store = DS.Store.create({ revision: 4}); 

App.Item = DS.Model.extend({ 
    id: DS.attr('string'), 
    name: DS.attr('string') 
}); 

App.store.createRecord(App.Item, {id: '4', name: 'banana' }); 
App.store.createRecord(App.Item, {id: '2', name: 'apple'}); 
App.store.createRecord(App.Item, {id: '6', name: 'spaghetti'}); 

App.ItemsController = Ember.ArrayController.create({ 
    content: App.store.findAll(App.Item), 
    sortProperties: ['name'] 
}); 

Mit der neuesten Version von Ember und Ember-Daten ergibt dies die Ausgabe:

[ id: 4, name: banana ] 

[ id: 2, name: apple ] 

[ id: 6, name: spaghetti ] 

Das Problem hier ist, Das App.store.findAll() gibt eine RecordArray zurück, deren Inhaltseigenschaft nicht einfach ein Array von App.Item Instanzen ist (in diesem Fall ist Inhalt [2, 3, 4])

Um tatsächlich die Instanzen in die Hände zu bekommen, muss ich etwas wie objectAt() verwenden. Aber selbst wenn ich die App.Item Instanzen aus dem RecordArray extrahiere und sie in einem gewöhnlichen Array ablege, funktionieren die Dinge nicht wie erwartet.

Fehle ich den offensichtlichen Weg, dies zu tun, oder ist dies nur der aktuelle Stand des Frameworks? Ich möchte lieber nicht alle meine Modelle als einfache Objekte replizieren, nur um sie zu sortieren.

EDIT:

ich rund um das Thema bekam durch ArrayController mein eigenes zu machen. Trotzdem wäre es schön, wenn die Dinge wie oben funktionieren würden.

EDIT # 2:

Original-Lenker Vorlage: (. Außerdem hatte ich eine sortProperty Eigenschaft statt sortProperties in meinem obigen Code verwendet, aber das war nur ein Tippfehler)

<script type="text/x-handlebars"> 
    {{#each App.ItemsController.content }} 
     <p>[ id: {{id}}, name: {{name}} ]</p> 
    {{/each}} 
</script> 

Und ja, wenn man stattdessen verwendet

<script type="text/x-handlebars"> 
    {{#each App.ItemsController.arrangedContent }} 
     <p>[ id: {{id}}, name: {{name}} ]</p> 
    {{/each}} 
</script> 
Dann

wir genau das bekommen, was wir wollen:

[ id: 2, name: apple ] 

[ id: 4, name: banana ] 

[ id: 6, name: spaghetti ] 
+5

Es tut mir leid, Sie haben keine besonders getan Gute Arbeit zu erklären, was hier nicht funktioniert, können Sie bitte Ihre Lenker-Vorlage in. Ich denke, es gibt ein kleines Problem, wo Sie manchmal an den 'arrangedContent'-Wert des' ArrayController 'binden müssen, um die korrekt geordneten Objekte zu erhalten. –

Antwort

6

Ab Ember 1.1.2 und ember-data 1.0.0-beta.3, und wahrscheinlich früher, nur sortProperties auf dem Controller einstellen ist genug. sortAscending kann auf true oder false eingestellt werden, je nachdem, welche Richtung Sie sortieren möchten.

App.ArrayController = Ember.ArrayController.extend({ 
    sortProperties: ['name'], 
    sortAscending: true 
}) 

Beachten Sie jedoch, dass

sortProperties: ['id'] 

erscheint Art lexikalisch, anstatt numerisch. Ich habe die lexikalische Sortierung mit einem created_at-Zeitstempel umgehen können, aber es kann einen anderen Weg geben.

+0

kann 'sortProperties' nach dem Laden dynamisch geändert werden? und wie wählst du aufsteigend oder absteigend? –

+0

Hinzugefügt in Bezug auf sortAscending. Was das Ändern der Sortierung betrifft, sieht es auch so aus - http://stackoverflow.com/questions/12476682/how-to-modify-the-sortproperties-value-dynamic-inside-an-ember- js-arraycontr –

11

Ich hatte das gleiche Problem. Dauerte eine Weile, aber schließlich diese allgemeine Lösung es gelöst:

App.ArrayController = Ember.ArrayController.extend({ 
    sortProperties: ['id'], 
    sortAscending: true, 

    sortedContent: (function() { 
    var content; 
    content = this.get("content") || []; 
    return Ember.ArrayProxy.createWithMixins(Ember.SortableMixin, { 
     content: content.toArray(), 
     sortProperties: this.get('sortProperties'), 
     sortAscending: this.get('sortAscending') 
    }); 
    }).property("[email protected]", 'sortProperties', 'sortAscending'), 

    doSort: function(sortBy) { 
    var previousSortBy; 
    previousSortBy = this.get('sortProperties.0'); 
    if (sortBy === previousSortBy) { 
     return this.set('sortAscending', !this.get('sortAscending')); 
    } else { 
     set('sortAscending', true); 
     return this.set('sortProperties', [sortBy]); 
    } 
    } 
}); 

Jetzt sind die meisten meiner ArrayControllers erweitern App.ArrayController statt Ember.ArrayController, insbesondere diejenigen, die Ember/Daten RecordArray s als Inhalt haben.

nun in Lenkern Vorlagen, dies zu tun:

{{#each item in sortedContent}} 
    ...   
{{/each}} 

statt

{{#each item in content}} 
    ...   
{{/each}} 
+0

Ich akzeptiere dies, da es mein Problem löst, aber wie Bradley Priest oben angedeutet hat, ist die Bindung an arrangedContent ausreichend. – ahmacleod

+0

Nur eine Anmerkung, ich fand, dass die Verwendung eines ArrayController anstelle eines ArrayProxy w/Mixin für mich arbeitete. Ich bin mir nicht sicher, welche anderen Nebenwirkungen es hat, aber es funktioniert einwandfrei. Ich habe gelesen, dass ArrayController eigentlich ArrayProxy mit den Mixins ist, aber es scheint sich nicht so zu verhalten. – mbseid

3

Ab Ember Version 1.0.0-rc.4 Ember.ArrayProxy.create(Ember.SortableMixin .... scheint nicht mehr zu funktionieren.Verwenden Sie Ember.ArrayProxy.createWithMixins(Ember.SortableMixin .... oder verwenden Sie die integrierten Sortierfunktionen in Ember.ArrayController.

+0

Danke, bearbeite die Antwort mit deiner Lösung :) –

4

Ich hatte ein ähnliches Problem und sortierte es über die docs for the array class
in meiner Route habe ich die sortBy() -Methode verwendet. so in Ihrem Fall könnte es so etwas wie

App.store.findAll().sortBy('name'); 

sein Ich weiß, dass dies eine alte Frage, aber es im Fall, dass jemand beantworten, wie ich auf stolpert von

+1

'this.store.findAll ('todo-list'). sortBy ('name')' gibt ein leeres Array an meinem Ende zurück, nicht sicher warum. – Link14

+0

macht das Entfernen der 'sortBy()' einen Unterschied? Nach welcher Eigenschaft möchten Sie sortieren? – Craicerjack

+1

Das ist mein Code 'var todoLists = this.store.findAll ('todo-list'). SortBy ('name');'. Wenn ich das 'sortBy()' entferne, sind die Ergebnisse korrekt. Das Modell, das ich bekomme, ist https://github.com/LouWii/ember-todo-list-app/blob/master/app/models/todo-list.js (das ganze Projekt ist eigentlich auf dem Github Repo). – Link14