Angular2 - Uncaught尝试使用被破坏的视图:detectChanges

时间:2016-05-23 20:04:37

标签: javascript typescript angular

所以我的应用程序一直给我这个错误:

extensions::uncaught_exception_handler:8 Error in event handler for runtime.onMessage: Attempt to use a destroyed view: detectChanges
at ViewDestroyedException.BaseException [as constructor] (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/@angular/core/core.umd.js:3776:27)
at new ViewDestroyedException (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/@angular/core/core.umd.js:6957:20)
at DebugAppView.AppView.throwDestroyedError (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/@angular/core/core.umd.js:10041:76)
at DebugAppView.AppView.detectChanges (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/@angular/core/core.umd.js:9994:22)
at DebugAppView.detectChanges (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/@angular/core/core.umd.js:10084:48)
at ViewRef_.detectChanges (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/@angular/core/core.umd.js:9397:69)
at SafeSubscriber.eval [as _next] (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/scripts/components/product-card.component.js:63:54)
at SafeSubscriber.__tryOrUnsub (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/rxjs/Subject/../bundles/Rx.umd.js:1408:16)
at SafeSubscriber.next (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/rxjs/Subject/../bundles/Rx.umd.js:1357:22)
at Subscriber._next (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/rxjs/Subject/../bundles/Rx.umd.js:1307:26)
at Subscriber.next (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/rxjs/Subject/../bundles/Rx.umd.js:1271:18)
at Subject._finalNext (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/rxjs/Subject/../bundles/Rx.umd.js:1063:30)
at Subject._next (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/rxjs/Subject/../bundles/Rx.umd.js:1055:18)
at Subject.next (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/rxjs/Subject/../bundles/Rx.umd.js:1012:14)handler @ extensions::uncaught_exception_handler:8(anonymous function) @ extensions::uncaught_exception_handler:100EventImpl.dispatch_ @ extensions::event_bindings:376EventImpl.dispatch @ extensions::event_bindings:393target.(anonymous function) @ extensions::SafeBuiltins:19publicClass.(anonymous function) @ extensions::utils:94messageListener @ extensions::messaging:189target.(anonymous function) @ extensions::SafeBuiltins:19EventImpl.dispatchToListener @ extensions::event_bindings:387target.(anonymous function) @ extensions::SafeBuiltins:19publicClass.(anonymous function) @ extensions::utils:94EventImpl.dispatch_ @ extensions::event_bindings:371EventImpl.dispatch @ extensions::event_bindings:393target.(anonymous function) @ extensions::SafeBuiltins:19publicClass.(anonymous function) @ extensions::utils:94dispatchOnMessage @ extensions::messaging:320

在组件的ChangeDetectorReference上调用detectChanges时:this._changeDetectorRef.detectChanges();

我遇到了类似的问题:

What is a dehydrated detector and how am I using one here?

和一些github问题:

https://github.com/angular/angular/issues/6786 https://github.com/angular/angular/issues/6786#issuecomment-185429140

这导致我这样调用detectChanges:

setTimeout( () => this._changeDetectorRef.detectChanges(), 10);

将错误更改为:

zone.js:260 Uncaught Attempt to use a destroyed view: detectChanges
Zone.runTask @ zone.js:260
ZoneTask.invoke @ zone.js:423

但它仍在发生。它没有破坏我的应用程序(它是在使用setTimeout之前),但我想弄清楚如何摆脱它。

我正在调用detectChanges(),因为后台发生的事情会改变应用程序的状态(而不是用户输入的结果)。调用detectChanges()时,不会新创建或即将销毁该组件。由于在后台发生的事情,组件的样式会发生变化。

3 个答案:

答案 0 :(得分:4)

在你的类的构造函数中给出:

setTimeout( () => this._changeDetectorRef.markForCheck(), 10);

在@component中:

changeDetection: ChangeDetectionStrategy.OnPush,

答案 1 :(得分:2)

由于subscribe()在视图已经更改后尝试执行完成代码,我的错误被抛出。

...
.then(response => {
    ...
    scope.cdr.detectChanges();
});
...

如果我快速切换视图或互联网速度很慢,就会发生这种情况。

创建视图时我创建了一个布尔值并设置为true:

view_active: Boolean = true

然后在视图被销毁时将其设置为false:

ngOnDestroy() {
    this.view_active = false
}

然后在调用detectChanges()

之前检查一下
...
.then(response => {
    ...
    if(scope.view_active) {
        scope.cdr.detectChanges();
    }
});
...

答案 2 :(得分:1)

或者你可以使用它:

import { ChangeDetectorRef, ViewRef } from '@angular/core';

setTimeout(() => {
  if(!(this.changeDetectorRef as ViewRef).destroyed) {
    this._changeDetectorRef.detectChanges();
  }
}, 10);