2016-05-13 7 views
2

Ich dachte, ich hätte dies mit reduce() herausgefunden, aber die Wendung ist, dass ich mehrere Eigenschaften auf jedem Datensatz zusammenrollen muss, also jedes Mal, wenn ich ein Objekt zurückgebe und Problem ist, dass previousValue ist ein Ember-Objekt, und ich ein einfaches Objekt zurückgeben, so funktioniert es gut in der ersten Schleife, aber das zweite Mal durch a ist nicht mehr ein Ember-Objekt, so dass ich einen Fehler bekomme sagen a.get is not a function. Beispielcode:Ember.js: Fasse Modellrekorde in einen Datensatz zusammen

/* 
filter the model to get only one food category, which is determined by the user selecting a choice that sets the property: theCategory 
*/ 
var foodByCategory = get(this, 'model').filter(function(rec) { 
    return get(rec, 'category') === theCategory; 
}); 

/* 
Now, roll up all the food records to get a total 
of all cost, salePrice, and weight 
*/ 
summary = foodByCategory.reduce(function(a,b){ 
    return { 
    cost: a.get('cost') + b.get('cost'), 
    salePrice: a.get('salePrice') + b.get('salePrice'), 
    weight: a.get('weight') + b.get('weight') 
    }; 
}); 

Ich gehe das alles falsch? Gibt es eine bessere Möglichkeit, mehrere Datensätze aus der model in einen Datensatz zusammenzufassen, oder muss ich die Modelldatensätze entweder zuerst in einfache Objekte oder alternativ in ein Ember-Objekt in der reduce() zurückgeben?

Edit: tun return Ember.Object.create({...}) funktioniert, aber ich würde immer noch eine gewisse Meinung gerne, ob dies der beste Weg, um das Ziel zu erreichen, oder wenn Ember bietet Funktionen, die dies tun wird, und wenn ja, ob sie sind besser als reduce.

+0

Verwenden Sie Glutendaten? –

+0

@selvaraj: Ja, ich bin – redOctober13

+0

Wo ist dieser Code? – locks

Antwort

0

this.get('model') Unter der Annahme gibt ein Ember.Enumerable, können Sie filterBy statt filter verwenden:

var foodByCategory = get(this, 'model').filterBy('category', theCategory); 

Was Ihre reduce, ich weiß nicht von irgendwelchen Ember Einbauten, die es verbessern würde. Das Beste, was ich denken kann ist, mehrere getrennte mapBy und reduce Anrufe mit:

summary = { 
    cost: foodByCategory.mapBy('cost').reduce(...), 
    salePrice: foodByCategory.mapBy('salePrice').reduce(...), 
    ... 
}; 

Aber das ist wahrscheinlich weniger performant. Ich würde mir nicht allzu viele Gedanken darüber machen, wie man Ember-eingebaute Standard-Datenmanipulationen durchführt ... Die meisten Ember-Projekte, die ich kenne, benutzen immer noch eine Hilfsbibliothek (wie Lodash) neben Ember selbst, was normalerweise effektiver ist, wenn man diese Art schreibt der Datentransformation.

+0

Danke. Mir ist klar, dass es JavaScript ist, um die Daten aufzurollen. Ist deiner Meinung nach 'reduce()' der beste Weg das zu tun? Im Grunde versuche ich ein neues Modell mit einem einzigen Datensatz zu erstellen. Ich füge auch zusätzliche Eigenschaften zu "Zusammenfassung" basierend auf den aufgerollten Eigenschaften hinzu. Soll ich das stattdessen in der Route tun, nach Kategorie dort aufrollen und dann nur 'filterBy' im Controller? – redOctober13

+0

@ redOctober13 hängt davon ab, was Sie mit "am besten" meinen. 'Reduzieren' ist definitiv ein guter Weg, es zu tun. Ich bin mir nicht sicher, ob ich genug Kontext habe, um zu sagen, was das Beste für deine Situation ist, aber es klingt wie "Zusammenfassung" ist ein erstklassiges Objekt in deiner App, auch wenn es kein Modell ist. Ich würde in Betracht ziehen, eine Zusammenfassung "Klasse" als const Zusammenfassung = Ember.Object.extend ({... ') zu erstellen, so dass Sie dort berechnete Eigenschaften auf eine mehr OO-Weise definieren können. Dann können Sie etwas wie" Zusammenfassung = Zusammenfassung "tun .create (foodByCategory.reduce (...)) ', wo Ihr' reduce' einen POJO zurückgibt. Lassen Sie mich wissen, ob mein Kommentar nicht klar ist. –

+0

@ redOctober13 Oh, noch etwas: Sie finden http://emberjs.com/api/# method_get ('Ember.get (obj, key)') nützlich: Es wird sowohl auf POJOs als auch 'Ember.Object' funktionieren. –