2012-09-22 10 views
8

Vorrei poter ordinare uno ArrayController il cui contenuto proviene da una query di dati di brace. Sfortunatamente, il mixin sortProperty non sembra funzionare in questo caso.Ordinamento di un controller Array supportato da Ember-Data tramite il mixin sortProperty

mi piacerebbe essere in grado di effettuare le seguenti operazioni:

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'] 
}); 

Con l'ultima versione di Ember e Ember-dati, questo dà l'output:

[ id: 4, name: banana ] 

[ id: 2, name: apple ] 

[ id: 6, name: spaghetti ] 

Il problema qui è che App.store.findAll() restituisce una RecordArray cui proprietà contenuto non è semplicemente un array di App.Item casi (in questo caso, il contenuto è [2, 3, 4])

Per mettere effettivamente le mani sulle istanze ho bisogno di usare qualcosa come objectAt(). Ma anche se estraggo le istanze dallo RecordArray e le scarico in un array ordinario, le cose non funzionano come previsto.

Mi manca il modo ovvio per farlo, o è solo lo stato attuale del framework? Preferirei non dover replicare tutti i miei modelli come oggetti semplici solo per ordinarli.

EDIT:

ho avuto tutto il problema facendo la mia personalizzato ArrayController. Comunque, sarebbe bello se le cose funzionassero come sopra.

EDIT # 2:

originale Manubrio modello: (. Inoltre, avevo usato una proprietà invece di sortProperties nel mio codice sopra sortProperty, ma che era solo un errore di battitura)

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

E sì, se si utilizza invece

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

Poi abbiamo ottenere esattamente quello che vogliamo:

[ id: 2, name: apple ] 

[ id: 4, name: banana ] 

[ id: 6, name: spaghetti ] 
+5

Mi dispiace, non avete fatto un particolare buon lavoro di spiegare cosa non funziona qui, puoi inserire il tuo modello di manubrio in. Penso che ci sia un piccolo problema dove a volte devi associare al valore 'arrangedContent' di' ArrayController' per ottenere gli oggetti ordinati correttamente. –

risposta

6

A partire da Ember 1.1.2 e da ember-data 1.0.0-beta.3, e probabilmente in precedenza, è sufficiente impostare sortProperties sul controller. sortAscending può essere impostato su true o false a seconda della direzione che si desidera ordinare.

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

Tuttavia, si noti che

sortProperties: ['id'] 

sembra sorta lessicale piuttosto che numericamente. Ho risolto l'ordinamento lessicale con un timestamp creato_at, ma potrebbe esserci un altro modo per aggirarlo.

+0

puoi 'sortProperties' essere cambiato dinamicamente dopo il caricamento? e come scegli di salire o scendere? –

+0

Aggiunto in riferimento a sortAscending. Inoltre, per quanto riguarda la modifica dinamica dell'ordinamento, sembra possibile: http://stackoverflow.com/questions/12476682/how-to-modify-the-sortproperties-value-dynamically-inside-an-ember- js-arraycontr –

11

Ho avuto lo stesso problema. Mi ha portato un po ', ma alla fine questa soluzione generale risolto:

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]); 
    } 
    } 
}); 

Ora la maggior parte dei miei ArrayControllers estendono App.ArrayController invece di Ember.ArrayController, in particolare quelli che hanno Ember/dati RecordArray s come contenuto.

Ora, nei modelli manubrio, fare questo:

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

invece di

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

Accetto questo poiché risolve il mio problema, ma, come indicato da Bradley Priest, è sufficiente il binding a arrangedContent. – ahmacleod

+0

Solo una nota, ho trovato che usare un controller Array invece di un ArrayProxy con mixin ha funzionato per me. Non sono sicuro di quali altri effetti collaterali ha, ma funziona in modo impeccabile. Ho letto che ArrayController è in realtà ArrayProxy con i mixins, ma non sembra comportarsi in questo modo. – mbseid

3

Come di Ember versione 1.0.0-rc.4 Ember.ArrayProxy.create(Ember.SortableMixin .... non sembra funzionare più.Utilizzare Ember.ArrayProxy.createWithMixins(Ember.SortableMixin .... o utilizzare le funzionalità di ordinamento integrate in Ember.ArrayController.

+0

Grazie, modificato la risposta con la tua correzione :) –

4

ho avuto un problema simile e ha risolto tramite la docs for the array class
nel mio percorso ho usato il metodo sortby(). Quindi nel tuo caso potrebbe essere qualcosa di simile a

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

So che questa è una vecchia questione, ma di rispondere in caso qualcuno, come me inciampa su da

+1

'this.store.findAll ('todo-list'). sortBy ('name')' sta restituendo una matrice vuota sulla mia estremità, non so perché. – Link14

+0

rimuove 'sortBy()' fa la differenza? quale proprietà stai cercando di ordinare? – Craicerjack

+1

Questo è il mio codice 'var todoLists = this.store.findAll ('todo-list'). SortBy ('name');'. Se rimuovo 'sortBy()', i risultati sono corretti. Il modello che sto ottenendo è https://github.com/LouWii/ember-todo-list-app/blob/master/app/models/todo-list.js (l'intero progetto si trova su quel repository di Github in realtà). – Link14