Ember router: asynchronous model (promises?)

[This is about the new router 1.0.0-pre.4 +.]

I want to return an entry from the Ember Route model method that requires asynchronous callbacks, for example, because this requires loading several (nested) models. What is the best way to do this?


Here is a sample code from a hypothetical blog application that illustrates the problem:

 App.Router.map -> @resource 'filteredArticles', path: '/:filter' App.FilteredArticlesRoute = Ember.Route.extend model: (params) -> blog = App.Blog.find(1) # get the user 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) 
+7
source share
2 answers

I am in the middle of rewriting Travis CI to the latest version of ember, and I am facing the same problem - we are retrieving repositories by slug (e.g. emberjs/ember.js ), which is not the primary key. My solution includes using Ember.ProxyObject .

When someone enters a path like /emberjs/ember.js , the parameters will look like this:

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

and thus slug will be equal to emberjs/ember.js .

With this information, I create a simple Ember object that simply saves the slug and isLoaded :

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

Then I create a proxy with this object as content:

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

Now I can download the record from the server using slug and return the proxy server as a model. When I get the record from the server, I just set the proxy contents to the actual record.

The full solution is here:

 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 

You can also take a look at the rest of the code on github

+4
source

How about adding an observer to the model itself, in the isLoaded state of the model, and then call blog.get(property)

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

All Articles