2013-02-11 75 views
7

[这是关于新的1.0.0-pre.4 +路由器。]灰烬路由器:异步模型(承诺?)

我想从灰烬路线的model方法返回一个需要异步回调至创纪录加载,例如因为它要求我们加载多个(嵌套)模型。什么是最好的方法来做到这一点?


下面是一个假设的博客应用程序示例代码,说明了这个问题:你怎么样在模型本身添加一个观察者,对模型的isLoaded状态,然后调用blog.get(property)

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

据我所知,如果你只是返回'blog.get(属性)'它将返回另一个承诺,这将被提取异步。 – 2013-02-11 15:29:08

+0

我希望它能做到,但它只是返回一个永远不会更新的空数组 - 即使重新运行App.Blog.find(1).get('articles')时产生一个非空数组。 – 2013-02-11 16:51:33

+0

感觉更像是一个github问题:) – 2013-02-11 17:59:24

回答

4

我在重写Travis CI到最新版本的余烬的中间和我面临同样的问题 - 我们取的塞库(例如emberjs/ember.js),这不是主键。我的解决方案涉及使用Ember.ProxyObject

当有人进入像/emberjs/ember.js道路,PARAMS将看起来像:

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

因此蛞蝓将等于emberjs/ember.js

利用这样的信息,创建简单余烬对象,它只是不断slugisLoaded属性:

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

然后,我创建与该对象作为内容的代理:

代理= Ember.ObjectProxy .create(content:content)

现在我可以使用slug从服务器加载记录并返回代理作为模型。当我从服务器获取记录时,我只需将代理内容设置为实际记录。

完整的解决方案是在这里:

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 

您还可以看看代码的其余on github

0

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