Ember router: Asynchronous model (promises?)
[This is about the new 1.0.0-pre.4+ router.]
I want to return from an Ember Route's model
method a record that needs asynchronous callbacks to load, for instance because it requires that we load multiple (nested) models. What's the best way to do this?
Here is sample code from a hypothetical blog app 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'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)
I'm in the middle of rewriting Travis CI to the newest ember version and I faced the same problem - we fetch repositories by slug (eg emberjs/ember.js
), which is not the primary key. My solution involves using Ember.ProxyObject
.
When someone enters the path like /emberjs/ember.js
, the params will look like:
{ owner: 'emberjs', name: 'ember.js` }
and thus slug will equal emberjs/ember.js
.
With such information, I create simple Ember object, which just keeps slug
and isLoaded
properties:
content = Ember.Object.create slug: slug, isLoaded: false
Then I create a proxy with this object as the content:
proxy = Ember.ObjectProxy.create(content: content)
Now I can load the record from the server using slug and return the proxy as the model. When I get the record from the server, I simply set proxies content to the actual record.
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
如何在模型本身中添加观察者,在模型的isLoaded状态上,然后调用blog.get(property)
blogReady: function() {
if(this.get('isLoaded') {
// switch logic
}
}.observes('isLoaded')
链接地址: http://www.djcxy.com/p/69148.html
上一篇: 如何在不退出REPL的情况下停止Clojure中的函数执行?
下一篇: Ember路由器:异步模式(承诺?)