2013-02-11 8 views
7

[Dies ist über die neuen 1.0.0-pre.4 + Router.]Ember Router: Asynchron-Modell (Versprechen?)

ich von einer Ember Route model Methode zurückkehren möge einen Datensatz, der auf asynchrone Rückrufe benötigt B. weil es erfordert, dass wir mehrere (verschachtelte) Modelle laden. Was ist der beste Weg, dies zu tun?


Hier ist Beispielcode von einem hypothetischen Blog-Anwendung, die das Problem veranschaulicht:

App.Router.map -> 
    @resource 'filteredArticles', path: '/:filter' 

App.FilteredArticlesRoute = Ember.Route.extend 
    model: (params) -> 
    blog = App.Blog.find(1) # get the user's Blog singleton 
    property = switch params.filter 
     when 'published' then 'publishedArticles' 
     when 'draft' then 'drafts' 
     when 'all' then 'articles' 
    # Return the list of articles from the `blog` record. 
    # But `blog` hasn't necessarily finished loading :(
    blog.get(property) 
+0

Was nehmen kann, wie ich wissen, wenn Sie zurückkommen nur 'blog.get (Eigentum)' es gibt ein anderes Versprechen zurück, das asynchron abgerufen wird. –

+0

Ich wünschte, es wäre, aber es gibt nur ein leeres Array zurück, das nie aktualisiert wird - selbst wenn "App.Blog.find (1) .get ('articles') 'erneut ausgeführt wird, ergibt sich ein nicht leeres Array. –

+0

Das fühlt sich mehr wie ein Github-Problem für mich an :) –

Antwort

4

ich bin in der Mitte Travis CI auf die neueste Version ember Umschreiben und ich vor dem gleichen Problem - wir holen Repositories von slug (z.B. emberjs/ember.js), die nicht der Primärschlüssel ist. Meine Lösung beinhaltet Ember.ProxyObject.

Wenn jemand betritt den Pfad wie /emberjs/ember.js, werden die params wie folgt aussehen:

{ owner: 'emberjs', name: 'ember.js` } 

und somit Slug emberjs/ember.js gleich wird.

Mit solchen Informationen schaffe ich einfach Ember-Objekt, das slug und isLoaded Eigenschaften nur hält:

content = Ember.Object.create slug: slug, isLoaded: false 

Dann erstelle ich einen Proxy mit diesem Objekt als Inhalt:

proxy = Ember.ObjectProxy .create (Inhalt: Inhalt)

Jetzt kann ich den Datensatz vom Server mit Hilfe von Slug laden und den Proxy als Modell zurückgeben. Wenn ich den Datensatz vom Server bekomme, setze ich den Proxy-Inhalt einfach auf den tatsächlichen Datensatz.

Voll Lösung ist hier:

deserialize: (params) -> 
    slug = "#{params.owner}/#{params.name}" 
    content = Ember.Object.create slug: slug, isLoaded: false 
    proxy = Ember.ObjectProxy.create(content: content) 

    repos = Travis.Repo.bySlug(slug) 

    observer = -> 
    if repos.get 'isLoaded' 
     repos.removeObserver 'isLoaded', observer 
     proxy.set 'content', repos.objectAt(0) 

    if repos.length 
    proxy.set('content', repos[0]) 
    else 
    repos.addObserver 'isLoaded', observer 

    proxy 

Sie auch einen Blick auf den Rest des Codes on github

0

Wie wäre es Ihnen, einen Beobachter in das Modell selbst, auf dem isLoaded Status des Modells hinzufügen und dann blog.get(property) nennen

blogReady: function() { 
    if(this.get('isLoaded') { 
    // switch logic 
    } 
}.observes('isLoaded') 
Verwandte Themen