2013-02-11 15 views
7

[Chodzi o nowym 1.0.0-pre.4 + router.]Ember Router: model asynchroniczny (obietnice?)

chcę wrócić z model sposobu wykonania Ember trasa jest zapis, który wymaga asynchronicznych wywołań zwrotnych do ładowanie, na przykład, ponieważ wymaga załadowania wielu (zagnieżdżonych) modeli. Jaki jest najlepszy sposób na zrobienie tego?


Oto przykładowy kod z hipotetycznej aplikacji bloga, który ilustruje problem:

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

O ile wiem, czy po prostu wrócić 'blog.get (właściwość)' go zwróci kolejną obietnicę, która zostanie sprowadzona asynchronicznie. –

+0

Chciałbym, żeby tak było, ale po prostu zwraca pustą tablicę, która nigdy się nie aktualizuje - nawet po ponownym uruchomieniu 'App.Blog.find (1) .get ('articles')' daje niepustą tablicę. –

+0

To wydaje mi się bardziej podobne do kwestii Githuba :) –

Odpowiedz

4

jestem w środku przepisywanie Travis CI do najnowszej wersji ember a ja w obliczu tego samego problemu - możemy sprowadzić repozytoriów przez ślimak (np. emberjs/ember.js), który nie jest kluczem podstawowym. Moje rozwiązanie wymaga użycia Ember.ProxyObject.

Kiedy ktoś wchodzi na ścieżkę jak /emberjs/ember.js, params będzie wyglądać następująco:

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

a więc ślimak będzie równa emberjs/ember.js.

Przy takiej informacji, tworzę prosty obiekt Ember, która tylko trzyma slug i isLoaded właściwości:

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

Następnie tworzę proxy z tego obiektu jako treść:

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

Teraz mogę załadować rekord z serwera za pomocą slug i zwrócić proxy jako model. Kiedy otrzymuję rekord z serwera, po prostu ustawiam zawartość proxy na aktualny rekord.

Pełna rozwiązaniem jest tutaj:

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 

Można również zapoznać się z resztą kodu on github

0

Jak o dodaniu obserwatora w samym modelu, od stanu isLoaded modelu, a następnie zadzwonić blog.get(property)

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