0

我有一个带有 2 个简单模型(ember-model)的简单 EmberJS 应用程序。帐户和项目,而一个帐户有许多项目。

因此,当我使用应用程序中的链接导航到 #/accounts/1/items 时,它工作得非常好。但是,当我直接重新加载 #/accounts/1/items 时出现错误:

Assertion failed: The value that #each loops over must be an Array. You passed <App.Account:ember335> (wrapped in (generated items controller)) ember.js?body=1:382
Uncaught TypeError: Object [object Object] has no method 'addArrayObserver' ember.js?body=1:19476
Assertion failed: Emptying a view in the inBuffer state is not allowed and should not happen under normal circumstances. Most likely there is a bug in your application. This may be due to excessive property change notifications. ember.js?body=1:382

这是我的应用程序的样子:

App.Router.map ()->
  @resource 'accounts', ->
    @resource 'account', path: ':account_id', ->
      @resource 'items'

App.AccountRoute = Ember.Route.extend
  model: (params) ->
    App.Account.find(params.account_id)

App.ItemsRoute = Ember.Route.extend
  model: ->
    @.modelFor('account').get('items')

App.Account = Ember.Model.extend
  name: Ember.attr('string')
  item_ids: Ember.attr(),
  items: (->
    App.Items.find(@.get('comment_ids'))
  ).property('comment_ids')

App.Item = Ember.Model.extend
  name: Ember.attr('string')

控制器是标准的(空的)。

在 JS 控制台中,这样的调用可以正常工作并返回正确的结果,即使在抛出错误之后(并且没有渲染):

 App.Account.find(1).get('items')

我不知道为什么会发生这种情况,而且代码看起来很简单,以至于没有线索真的很烦人。有人有想法吗?

4

1 回答 1

0

我不是 ember-data 专家,但似乎它正在返回一个承诺。因此,您应该尝试:

App.ItemsRoute = Ember.Route.extend({
  model : function(){
    var accountPromise = App.Account.find(1);
    var itemsPromise = Ember.Deferred.create();
    accountPromise.then(function(account){
      itemsPromise.resolve(account.get("items"));
    });
    return itemsPromise;
  }
});

为什么一定要这样?

  1. App.Account.find(1);执行异步调用并因此返回一个承诺。
  2. 这就是为什么您不能立即退货的原因,您必须等待 accountPromise 履行。
  3. 您返回一个新的承诺 ( itemspromise),它会在 accountPromise 得到满足时得到满足。
  4. 因为您返回了一个 Promise,所以 Ember 等待它完成并将结果用作您的 Controller 的模型。

PS:实际上这对我来说似乎有点复杂。我认为这会起作用,但可能会有更优雅的解决方案。

于 2013-08-28T13:04:39.747 回答