【问题标题】:EmberJS "assertion failed: calling set on destroyed object" after unloading and reloading models卸载和重新加载模型后,EmberJS“断言失败:在被破坏的对象上调用 set”
【发布时间】:2017-06-09 13:56:05
【问题描述】:

在进行 API 调用时,我无法卸载数据模型并正确地重新填充它们。

模型:

/* Model Foo */
export default DS.Model.extend({
  bars: DS.hasMany('bar', { async: true })
});

/* Model Bar */
export default DS.Model.extend({
  foo: DS.belongsTo('foo', { async: true, inverse: 'bars' })
});

在应用程序中的某个时间点,foo 和 bar 都从 ember 数据存储中卸载,然后从 API 调用中重新加载。像这样:

/* Unload and reload snippet */
this.store.unloadAll('bar');
this.store.unloadAll('foo');

let bars = this.store.filter('bar', { 
  queryParam: x 
}, function(bar) {
  return x === bar.x
});

let foos = this.store.filter('foo', { 
  queryParam: y 
}, function(foo) {
  return y === bar.y
});

let self = this;
Ember.RSVP.all([foos, bars]).finally(function() {
  self.controller.set('model.foos', foos);
  self.controller.set('model.bars', bars);
});

问题出现在依赖于这些模型更改的计算属性中。

/* Computed property elsewhere in app */
compProp: Ember.computed('foo.bars.[]', function() {
  let tmp = this.get('foo.bars'); /* <-- Error generating line */
  .
  .
  .
})

这一行给了我以下错误: Assertion Failed: calling set on destroyed object: &lt;DS.PromiseManyArray:ember1995&gt;.content = &lt;DS.ManyArray:ember3320&gt;

错误的堆栈跟踪:

Assertion Failed: calling set on destroyed object: <DS.PromiseManyArray:ember1014>.content = <DS.ManyArray:ember1348>
Error
    at assert (http://localhost:4200/assets/vendor-3e8430b320dbe268f7ee6486de4c6cad.js:23072:13)
    at Object.assert (http://localhost:4200/assets/vendor-3e8430b320dbe268f7ee6486de4c6cad.js:23285:34)
    at Object.set (http://localhost:4200/assets/vendor-3e8430b320dbe268f7ee6486de4c6cad.js:39281:17)
    at Class.set (http://localhost:4200/assets/vendor-3e8430b320dbe268f7ee6486de4c6cad.js:52151:26)
    at ManyRelationship._updateLoadingPromise (http://localhost:4200/assets/vendor-3e8430b320dbe268f7ee6486de4c6cad.js:152522:33)
    at ManyRelationship.getRecords (http://localhost:4200/assets/vendor-3e8430b320dbe268f7ee6486de4c6cad.js:152723:21)
    at Class.get (http://localhost:4200/assets/vendor-3e8430b320dbe268f7ee6486de4c6cad.js:152101:60)
    at ComputedPropertyPrototype.get (http://localhost:4200/assets/vendor-3e8430b320dbe268f7ee6486de4c6cad.js:34367:28)
    at get (http://localhost:4200/assets/vendor-3e8430b320dbe268f7ee6486de4c6cad.js:39184:19)
    at _getPath (http://localhost:4200/assets/vendor-3e8430b320dbe268f7ee6486de4c6cad.js:39205:13)
    at Object.get (http://localhost:4200/assets/vendor-3e8430b320dbe268f7ee6486de4c6cad.js:39180:14)

感谢您的帮助!

旁注:

  • 我知道store.filter() 已被弃用。我正在从早期的 Ember 版本升级应用程序,并使用 ember-data-filter 插件来实现临时兼容性。
  • 这适用于 Ember 1.13。

更新

为了不让这个问题悬而未决,我一直无法找到问题。

我的解决方案是删除所有 unloadAll() 呼叫并根据需要单独管理记录。

【问题讨论】:

    标签: ember.js ember-data


    【解决方案1】:

    这可能是由 ember 破坏的元素上发生的任何异步 set 引起的。因此,追踪起来可能很棘手。我通常在 chrome 开发者控制台中打开“pause on caught exceptions”来查找导致问题的set

    【讨论】:

    • 看起来 set 正在 Ember 内部发生。我在 has-many.js 中发现了它。有一个执行this._loadingPromise.set('content', content)_updateLoadingPromise 方法。 this好像是指RecordArrayManager吧。我不熟悉 Ember 的内部工作原理,所以我不知道为什么在尝试 get 数据时会出现 set
    • 如果您检查异常时的调用堆栈,您应该能够准确地看到代码中的哪个位置有一个 set 试图修改已破坏对象上的数据(可能是一个组件不再存在)
    • 一个简单的例子是一个通过 ajax 加载一些数据并在回调中运行 set(this, 'dataField', serverData) 的组件。如果用户在数据加载过程中转到另一个路由,回调仍然会触发,但组件将不再存在,因此异常将被 ember 捕获并记录。
    • 对不起,我不清楚。我评论中的信息来自使用“暂停捕获的异常”并检查调用堆栈。堆栈跟踪中的唯一设置是我在上面的评论中提到的那个。我还添加了确切的堆栈跟踪。
    • 好吧,我现在明白了。不幸的是,这似乎超出了我的技能范围。我会把这个带到 ember 社区 slack 的通用频道。
    猜你喜欢
    • 2014-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多