【问题标题】:Uncaught Error: Assertion Failed: calling set on destroyed object未捕获的错误:断言失败:在被破坏的对象上调用 set
【发布时间】:2014-09-28 07:01:40
【问题描述】:

从事 ember-cli 测试。在所有测试都通过后,它会返回额外的两个错误测试。

未捕获的错误:断言失败:在已破坏对象上调用 set 来源:'../dist/assets/vendor.js:13269'

这是一个单元测试配置

import Ember from "ember";
import { test,moduleFor } from 'ember-qunit';
import startApp from '../helpers/start-app';

var App;

module('An Integration test',{
    setup:function(){
        App=startApp();
    },
    teardown: function() {
        Ember.run(App, 'destroy');
    }
});

【问题讨论】:

  • 你有没有想过这个问题?

标签: ember.js qunit ember-cli


【解决方案1】:

这是因为在 promise 或任何其他延迟代码的结果中,您没有检查对象的销毁状态,或者因为您没有拆除已设置并与 DOM 事件或任何外部事件交互的东西Ember 的核心。

我曾经在一些映射到 Ember 的 jQuery 插件上遇到这种情况,并且在测试期间插件销毁太慢,然后我要么不使用运行循环,要么不检查 Ember 对象的销毁状态我在操纵。

您可以这样做:

if ( !(obj.get('isDestroyed') || obj.get('isDestroying')) ) {
  // do your destroying code setting stuff
}

还要考虑销毁可能已在您的视图代码中初始化的任何 jQuery 插件(例如,didInsertElement 中的任何设置都应该在 willDestroyElement 中拆除)。

【讨论】:

  • 你所说的“//你破坏代码设置的东西”到底是什么意思?我在调用一些 this.$(document).on('click', '.myEl', function() { // do something }); 时遇到同样的问题。我注意到当用户导航到不同的路线并返回到具有上述代码的路线时,此点击处理程序不起作用。请注意,点击处理程序位于视图中。
  • 你不应该听这样的事件。如果单击事件与视图相关,则必须改用视图的eventManager 属性(请参阅emberjs.com/api/classes/Ember.View.html#toc_event-managers)。无论如何,您可能已经听过一些 jQuery 事件并尝试调用 ember 对象的一些方法(包括 get/set)。如果是这样,请务必删除 willDestroyElement 中的事件侦听器,如果不能,请用我写的 if 包围事件函数的主体,以便在 Ember 对象已经被销毁或正在销毁的情况下,您不会有错误
  • 我确实将我的 jQuery 选择器包装在您共享的 if 语句中。我只用 Ember 对象的“this”替换了 obj。那是正确的方法吗?我仍然看到错误。
  • @Nagarjun 我会将链接的答案添加为该问题的另一个答案。
  • 未来旅行者:如需在整个 Ember 应用中避免此问题的可靠方法,请探索 ember-concurrency.com
【解决方案2】:

好吧,我在类似的事情上苦苦挣扎。所以基本上当你在一个承诺中有“this.set()”时,可能会发生承诺需要很长时间才能解决,并且用户已经点击离开该页面,在这种情况下你正在尝试设置一些东西,即已经被摧毁了。我发现最简单的解决方案就是在 promise 的开头做一个简单的检查。

if (this.isDestroyed) {
    return;
}
this.set('...');
...

编辑:或者你可以使用Ember.trySet

【讨论】:

  • 嗨..你为此做了什么
【解决方案3】:

该问题与未完全解决的承诺以及之后立即运行的另一个测试有关。

你应该试试Ember Concurrency

从'ember-concurrency'导入{任务,超时};

myFunction: task(function * () {

  // do somethinng

  yield timeout(1000); // wait for x milliseconds

  // do something else

}).drop(),

【讨论】:

    【解决方案4】:

    我在集成测试中遇到了类似的问题。为了解决这个问题,在集成测试中,我在执行下一个操作之前等待。

    import wait from 'ember-test-helpers/wait';
    wait().then(() => {
    // perform action (which previously used to cause an exception)
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-29
      • 1970-01-01
      相关资源
      最近更新 更多