Ich habe meinen Anwendungsfall vereinfacht, damit die Frage leichter zu verstehen und zu beantworten ist. Nehmen wir an, wir haben 3 Modelle: Country
, Region
und Area
:
Der Model-Hook der Route sollte ein Array von Objekten zurückgeben. So:
%Vor%Hinweis: Die Einrückungen sind only , um das Beispiel lesbarer zu machen.
Ich bekomme Error while loading route: TypeError: Object [object Array] has no method 'then'
, was offensichtlich von diesem Code herrührt:
Aber das sollte das wirkliche Problem zeigen, das ich habe:
Ich brauche countries
aufgelöst, um regions
zu erhalten, was wiederum die areas
erfordert. Ich habe die Funktionen RSVP.hash
und RSVP.all
überprüft, die offizielle API gelesen und dieses Gespräch verfolgt. Allerdings schaffe ich es nicht, den richtigen Code zu erstellen, um Versprechen zu verketten, und im letzten then
modifiziere das zurückgegebene Ergebnis, um meine Erwartungen zu erfüllen.
Mir wurde gesagt, dass das Laden von Daten wie dieser viele HTTP-Anfragen verursachen kann und wahrscheinlich würde dies besser durch Sideloading gelöst werden, aber:
FixturesAdapter
, also sind HTTP-Anfragen kein Problem Deshalb ist es mir wichtig, herauszufinden, wie dies richtig gemacht werden sollte.
Ich habe ein JSBin für mein Beispiel mit den von kingpin2k's anwser vorgeschlagenen Änderungen erstellt.
Während der Code funktioniert, sind die Ergebnisse ... unerwartet :
countries
-Array habe ich sowohl country
als auch region
Objekte gefunden. Warum?
country
und region
scheinen geladen zu sein, die Bereiche jedoch nicht (siehe Konsolenprotokoll in JSBin). Warum?
Also ... jetzt habe ich endlich alle Objekte korrekt aufgelöst (Länder, Regionen, Gebiete) und kann meine Arbeit fortsetzen:)
Der Trick besteht darin, dass Sie bestimmte Versprechen lösen müssen, bevor Sie auf die Eigenschaften dieser Datensätze zugreifen können. Ember.RSVP.all
benötigt ein Array von Versprechen. Ember.RSVP.hash
nimmt einen Hash von Versprechen. Leider sind Sie in der Situation, wo Sie Ihre Versprechen nicht aufbauen können, bis die vorherigen Versprechen gelöst sind (a la, Sie wissen nicht, welche regions
zu bekommen sind, bis die countries
aufgelöst sind, und Sie nicht wissen welche areas
bekommen bis die regions
aufgelöst sind). In diesem Fall haben Sie wirklich eine Reihe von Versprechen zu holen (wenn auch Arrays von Versprechen auf jeder Ebene). Ember weiß zu warten, bis sich das tiefste Versprechen aufgelöst hat und diesen Wert als Modell zu verwenden.
Jetzt müssen wir so tun, als ob regions
und area
async sind, wenn sie es nicht sind, erzählen Sie Ember Data, dass die Information in der Anfrage mit country
enthalten sein wird, oder in der Anfrage mit region
und diese Sammlungen sind keine Versprechen, also würde der Code, den ich unten eingefügt habe, nicht funktionieren.
Da dies so aussieht, als ob Sie Ember Data verwenden würden, würde ich einfach this.store.find('country')
zurückgeben und Ember Data die Daten holen lassen, wenn es verwendet wird ... Diese Vorlage würde ohne all diesen Versprechenscode funktionieren, und würde füllen, wie Ember Data die Versprechungen selbst erfüllt (es wird die Daten anfordern, sobald es sieht, dass Sie versucht haben, die Daten zu verwenden, gute alte Lazy Loading).
Wenn Sie hier sind, machen Sie wahrscheinlich den gleichen Fehler wie ich :)
Wenn Sie einen komplizierten Baum von Objekten benötigen, um Ihre Route anzuzeigen, können Sie auch:
this.store.find('mymodel', model_id)
Allerdings lasse ich den ursprünglichen anwser als "akzeptiert" markiert, da er die ursprüngliche Frage tatsächlich beantwortet, und diese Antwort ist nur eine Anmerkung für zukünftige Referenzen / andere Benutzer.
Tags und Links javascript ember.js ember-data rsvp-promise