Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 尝试使用已销毁的视图:detectChanges_Angular_Angular2 Meteor - Fatal编程技术网

Angular 尝试使用已销毁的视图:detectChanges

Angular 尝试使用已销毁的视图:detectChanges,angular,angular2-meteor,Angular,Angular2 Meteor,我正在使用AngularMeteor2创建一个简单的UI 1) 我有一个顶部导航栏组件,其中有一个“注销”按钮。 2) 单击“注销”按钮,它将重定向到“登录”。 3) 然后我在控制台中看到这个错误:异常:尝试使用已销毁的视图:detectChanges 例外情况: EXCEPTION: Attempt to use a destroyed view: detectChanges browser_adapter.js:77 EXCEPTION: Attempt to use a destroyed

我正在使用AngularMeteor2创建一个简单的UI

1) 我有一个顶部导航栏组件,其中有一个“注销”按钮。
2) 单击“注销”按钮,它将重定向到“登录”。
3) 然后我在控制台中看到这个错误:
异常:尝试使用已销毁的视图:detectChanges

例外情况:

EXCEPTION: Attempt to use a destroyed view: detectChanges
browser_adapter.js:77 EXCEPTION: Attempt to use a destroyed view: detectChangesBrowserDomAdapter.logError @ browser_adapter.js:77BrowserDomAdapter.logGroup @ browser_adapter.js:87ExceptionHandler.call @ exception_handler.js:57(anonymous function) @ application_ref.js:265schedulerFn @ async.js:123SafeSubscriber.__tryOrUnsub @ Subscriber.js:225SafeSubscriber.next @ Subscriber.js:174Subscriber._next @ Subscriber.js:124Subscriber.next @ Subscriber.js:88Subject._finalNext @ Subject.js:128Subject._next @ Subject.js:120Subject.next @ Subject.js:77EventEmitter.emit @ async.js:112onError @ ng_zone.js:120onHandleError @ ng_zone_impl.js:66ZoneDelegate.handleError @ angular2-polyfills.js:394Zone.runTask @ angular2-polyfills.js:323ZoneTask.invoke @ angular2-polyfills.js:490
browser_adapter.js:77 STACKTRACE:BrowserDomAdapter.logError @ browser_adapter.js:77ExceptionHandler.call @ exception_handler.js:59(anonymous function) @ application_ref.js:265schedulerFn @ async.js:123SafeSubscriber.__tryOrUnsub @ Subscriber.js:225SafeSubscriber.next @ Subscriber.js:174Subscriber._next @ Subscriber.js:124Subscriber.next @ Subscriber.js:88Subject._finalNext @ Subject.js:128Subject._next @ Subject.js:120Subject.next @ Subject.js:77EventEmitter.emit @ async.js:112onError @ ng_zone.js:120onHandleError @ ng_zone_impl.js:66ZoneDelegate.handleError @ angular2-polyfills.js:394Zone.runTask @ angular2-polyfills.js:323ZoneTask.invoke @ angular2-polyfills.js:490
browser_adapter.js:77 Error: Attempt to use a destroyed view: detectChanges
    at ViewDestroyedException.BaseException [as constructor] (http://localhost:3000/packages/modules.js?hash=560db94ec01c0b3e8f499491ffcce7a2ec6c3c5e:3349:23)
    at new ViewDestroyedException (http://localhost:3000/packages/modules.js?hash=560db94ec01c0b3e8f499491ffcce7a2ec6c3c5e:10626:16)
    at DebugAppView.AppView.throwDestroyedError (http://localhost:3000/packages/modules.js?hash=560db94ec01c0b3e8f499491ffcce7a2ec6c3c5e:11277:72)
    at DebugAppView.AppView.detectChanges (http://localhost:3000/packages/modules.js?hash=560db94ec01c0b3e8f499491ffcce7a2ec6c3c5e:11230:18)
    at DebugAppView.detectChanges (http://localhost:3000/packages/modules.js?hash=560db94ec01c0b3e8f499491ffcce7a2ec6c3c5e:11321:44)
    at ViewRef_.detectChanges (http://localhost:3000/packages/modules.js?hash=560db94ec01c0b3e8f499491ffcce7a2ec6c3c5e:11011:65)
    at http://localhost:3000/app/app.js?hash=323b1216814e80ed467d95bcda255eb217d7c468:2224:23
    at ZoneDelegate.invokeTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4721:174)
    at Object.onInvokeTask (http://localhost:3000/packages/modules.js?hash=560db94ec01c0b3e8f499491ffcce7a2ec6c3c5e:9393:41)
    at ZoneDelegate.invokeTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4721:72)
  -------------   Elapsed: 80 ms; At: Wed Jun 15 2016 20:22:09 GMT-0700 (PDT)   -------------  
    at Object.onScheduleTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:5734:30)
    at ZoneDelegate.scheduleTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4704:57)
    at Zone.scheduleMacroTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4652:47)
    at http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4467:37
    at setTimeout (eval at createNamedFn (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:5346:24), <anonymous>:3:37)
    at new TopNavbarComponent (http://localhost:3000/app/app.js?hash=323b1216814e80ed467d95bcda255eb217d7c468:2221:9)
    at DebugAppView._View_HomeComponent0.createInternal (HomeComponent.template.js:48:34)
    at DebugAppView.AppView.create (http://localhost:3000/packages/modules.js?hash=560db94ec01c0b3e8f499491ffcce7a2ec6c3c5e:11098:21)
  -------------   Elapsed: 2 ms; At: Wed Jun 15 2016 20:22:09 GMT-0700 (PDT)   -------------  
    at Object.onScheduleTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:5734:30)
    at ZoneDelegate.scheduleTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4704:57)
    at Zone.scheduleMicroTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4649:47)
    at scheduleResolveOrReject (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4928:22)
    at resolvePromise (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4893:29)
    at http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4930:25
    at ZoneDelegate.invokeTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4721:174)
    at Object.onInvokeTask (http://localhost:3000/packages/modules.js?hash=560db94ec01c0b3e8f499491ffcce7a2ec6c3c5e:9393:41)
  -------------   Elapsed: 0 ms; At: Wed Jun 15 2016 20:22:09 GMT-0700 (PDT)   -------------  
    at Object.onScheduleTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:5734:30)
    at ZoneDelegate.scheduleTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4704:57)
    at Zone.scheduleMicroTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4649:47)
    at scheduleResolveOrReject (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4928:22)
    at ZoneAwarePromise.then (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:5011:25)
    at RuntimeCompiler.resolveComponent (http://localhost:3000/packages/modules.js?hash=560db94ec01c0b3e8f499491ffcce7a2ec6c3c5e:40230:14)
    at DynamicComponentLoader_.loadNextToLocation (http://localhost:3000/packages/modules.js?hash=560db94ec01c0b3e8f499491ffcce7a2ec6c3c5e:10788:31)
    at RouterOutlet.activate (http://localhost:3000/packages/modules.js?hash=560db94ec01c0b3e8f499491ffcce7a2ec6c3c5e:26844:26)
  -------------   Elapsed: 0 ms; At: Wed Jun 15 2016 20:22:09 GMT-0700 (PDT)   -------------  
    at Object.onScheduleTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:5734:30)
    at ZoneDelegate.scheduleTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4704:57)
    at Zone.scheduleMicroTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4649:47)
    at scheduleResolveOrReject (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4928:22)
    at resolvePromise (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4893:29)
    at http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4877:21
    at ZoneDelegate.invoke (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4696:161)
    at Object.onInvoke (http://localhost:3000/packages/modules.js?hash=560db94ec01c0b3e8f499491ffcce7a2ec6c3c5e:9402:41)
  -------------   Elapsed: 0 ms; At: Wed Jun 15 2016 20:22:09 GMT-0700 (PDT)   -------------  
    at Object.onScheduleTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:5734:30)
    at ZoneDelegate.scheduleTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4704:57)
    at Zone.scheduleMicroTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4649:47)
    at scheduleResolveOrReject (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4928:22)
    at resolvePromise (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4893:29)
    at http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4877:21
    at ZoneDelegate.invoke (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4696:161)
    at Object.onInvoke (http://localhost:3000/packages/modules.js?hash=560db94ec01c0b3e8f499491ffcce7a2ec6c3c5e:9402:41)
  -------------   Elapsed: 0 ms; At: Wed Jun 15 2016 20:22:09 GMT-0700 (PDT)   -------------  
    at Object.onScheduleTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:5734:30)
    at ZoneDelegate.scheduleTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4704:57)
    at Zone.scheduleMicroTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4649:47)
    at scheduleResolveOrReject (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4928:22)
    at resolvePromise (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4893:29)
    at http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4930:25
    at ZoneDelegate.invokeTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4721:174)
    at Object.onInvokeTask (http://localhost:3000/packages/modules.js?hash=560db94ec01c0b3e8f499491ffcce7a2ec6c3c5e:9393:41)
  -------------   Elapsed: 1 ms; At: Wed Jun 15 2016 20:22:09 GMT-0700 (PDT)   -------------  
    at Object.onScheduleTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:5734:30)
    at ZoneDelegate.scheduleTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4704:57)
    at Zone.scheduleMicroTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4649:47)
    at scheduleResolveOrReject (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4928:22)
    at ZoneAwarePromise.then (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:5011:25)
    at http://localhost:3000/packages/modules.js?hash=560db94ec01c0b3e8f499491ffcce7a2ec6c3c5e:26895:53
    at http://localhost:3000/packages/meteor.js?hash=ae8b8affa9680bf9720bd8f7fa112f13a62f71c3:1105:22
    at ZoneDelegate.invoke (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4696:161)
  -------------   Elapsed: 0 ms; At: Wed Jun 15 2016 20:22:09 GMT-0700 (PDT)   -------------  
    at Object.onScheduleTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:5734:30)
    at ZoneDelegate.scheduleTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4704:57)
    at Zone.scheduleMicroTask (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4649:47)
    at scheduleResolveOrReject (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4928:22)
    at resolvePromise (http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4893:29)
    at http://localhost:3000/packages/barbatus_angular2-runtime.js?hash=fda9b73362c52e988ad030102a9f58e4d584cda3:4877:21
    at http://localhost:3000/packages/meteor.js?hash=ae8b8affa9680bf9720bd8f7fa112f13a62f71c3:1105:22BrowserDomAdapter.logError @ browser_adapter.js:77ExceptionHandler.call @ exception_handler.js:60(anonymous function) @ application_ref.js:265schedulerFn @ async.js:123SafeSubscriber.__tryOrUnsub @ Subscriber.js:225SafeSubscriber.next @ Subscriber.js:174Subscriber._next @ Subscriber.js:124Subscriber.next @ Subscriber.js:88Subject._finalNext @ Subject.js:128Subject._next @ Subject.js:120Subject.next @ Subject.js:77EventEmitter.emit @ async.js:112onError @ ng_zone.js:120onHandleError @ ng_zone_impl.js:66ZoneDelegate.handleError @ angular2-polyfills.js:394Zone.runTask @ angular2-polyfills.js:323ZoneTask.invoke @ angular2-polyfills.js:490
Subscriber.js:229 Uncaught Attempt to use a destroyed view: detectChanges
这是我的login.component.ts

"use strict";
import {Logger} from "../services/logger.service";
import {Component, ChangeDetectionStrategy, ChangeDetectorRef} from '@angular/core';
import {User} from "../models/user";
import {Router} from '@angular/router-deprecated';
import {UserService} from "../services/user.service";
import {CORE_DIRECTIVES} from '@angular/common';
import {DROPDOWN_DIRECTIVES} from '../../node_modules/ng2-bootstrap';

@Component({
    selector: 'top-navbar',
    templateUrl: 'client/top-navbar/top-navbar.html',
    bindings: [UserService, Logger],
    directives: [CORE_DIRECTIVES, DROPDOWN_DIRECTIVES]
})

export class TopNavbarComponent {

    public user:User;

    public statusDropdown = {
        isOpen: false
    };

    constructor(private userService:UserService, private router:Router, private logger:Logger, private ref:ChangeDetectorRef) {
        setTimeout(() => {
            this.ref.markForCheck();
            this.user = this.userService.getLoggedInUser();
            this.ref.detectChanges();
        }, 0)
    }

    logout() {
        this.logger.warn('[Top Navbar] Logging out the user.');
        localStorage.clear();
        this.router.navigateByUrl('/login');
    }
}
"use strict";
import { Component, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { FormBuilder, ControlGroup, Validators } from '@angular/common';
import { MeteorComponent } from 'angular2-meteor';
import { Router } from '@angular/router-deprecated';
import { Logger } from "../services/logger.service";

@Component({
    selector: 'login',
    templateUrl: 'client/login/login.html',
    changeDetection: ChangeDetectionStrategy.OnPush,
    bindings: [Logger]
})

export class LoginComponent extends MeteorComponent {

    loginForm:ControlGroup;
    loginFailed = false;

    constructor(private _logger:Logger, private _router:Router, private ref:ChangeDetectorRef) {
        super();
        let fb = new FormBuilder();
        this.loginForm = fb.group({
            username: ["", Validators.required],
            password: ["", Validators.required]
        });
    }

    login() {


        this.call('authenticateUser', this.loginForm.value.username, this.loginForm.value.password, (err, data) => {

            if (err) {
                this._logger.error(err);

            } else {
                this._logger.info('[Authentication API] ', data);

                if (data.status != 'LOGIN_SUCCESS') {
                    this.loginFailed = true;

                } else {
                    this.loginFailed = false    ;
                    var user = {
                        id: data.id,
                        name: data.name,
                        role: data.role
                    }
                    localStorage.setItem('user', JSON.stringify(user));
                    this._router.navigate(['Home'])
                }
                //This is required for letting Angular know that something has changed.
                //Because this part of code runs out of Angular zone.
                this.ref.markForCheck();  // Mark this component and its children for change detection in next detecting cycle.
                this.ref.detectChanges(); // Trigger change detection.

            }

        });
    }
}

我解决了与您相同的问题,但代码要小得多,我将告诉您可以帮助您解决问题的要点

问题显然来自
detectChanges()
,因为更改是在组件的销毁阶段完成的,并且调用了方法

因此,您需要将组件设置为
实现OnDestroy
,然后需要取消将
this.ref.detectChanges()
调用的更改。因此,您的
TopNavbarComponent
必须类似于:

export class TopNavbarComponent implements OnDestroy {
  // ... your code

  ngOnDestroy() {
    this.cdRef.detach(); // do this

    // for me I was detecting changes using `detectChanges()` inside a subscription with `subscribe()` to observable without limitation, so was enough for me to just `unsubscribe()` like the following line;
    // this.authObserver.unsubscribe();
  }
}
注意:不要忘记
取消订阅()
组件中的所有观察者!无论如何,你必须这样做,没有取消订阅的订阅可能是包括此在内的数百个问题的主要原因,请参阅

编辑: 我知道web上还有其他解决方案试图通过处理错误本身来解决问题,而最佳实践是了解问题的根源,检查视图是否被破坏是一个很好的解决方案,因为最初的原因可能是内存泄漏背后的问题,谁知道呢!因此,问题的根源在于需要终止正在运行的服务,而不仅仅是在不知道问题根源的情况下尝试终止错误本身,例如,必须关闭正在运行的订阅(尤其是自定义订阅)


所以!家政用品对于更好的性能是必要的,它并不总是一个更简单、更快的解决方案是更好的,如果你确实把脏东西藏在地毯下面,并不意味着你“清洁”您的房间即使看起来确实不错:)

您必须在变量中获取subscriber的值,并使用相同的变量取消订阅。请参考以下相同代码

import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { Cartservice } from './../cartservice.service';
import { ISubscription } from 'rxjs/Subscription';



export class CartComponent implements OnInit, OnDestroy {

private subscription: ISubscription;
ngOnInit() {
    this.subscription = this.cartservice.productsObservable.subscribe(cart => {
      this.cartProducts = cart.products;
      this.cartTotal = cart.cartTotal;
      this.changeDetectorRef.detectChanges();
    });
  }

 ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

请注意,我已取消订阅方法Ngondestory()中的更改。

唯一适合我的解决方案是:

if (!this.changeDetectionRef['destroyed']) {
    this.changeDetectionRef.detectChanges();
}
你可以用

this.cdref.markForCheck();

而不是
this.cdref.detectChanges();

在许多情况下。但最好的方法是遵循@Al-Mothafar技巧。在我的例子中,这是一个组件配置和编译的异步测试设置管理不当的问题

  • 失败的代码有一个使用
  • 为了让它工作,我使用了两个beforeach()函数,第一个处理异步使用,第二个处理异步使用 导致错误的代码

    beforeEach(async () => {
        await TestBed.configureTestingModule({
            imports: [
                BrowserAnimationsModule
            ],
            providers: [
                { provide: ComponentFixtureAutoDetect, useValue: true },
                { provide: OptionsService, useValue: optionServiceMock },
            ],
            declarations: [EventLogFilterComponent],
            schemas: [NO_ERRORS_SCHEMA]
        }).compileComponents();
        fixture = TestBed.createComponent(EventLogFilterComponent);
        component = fixture.componentInstance;
        optionsService = TestBed.get(OptionsService);
        component.filterElem = jasmine.createSpyObj('filterElem', ['close']);
        fixture.detectChanges();
    });
    
    是用

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [
                BrowserAnimationsModule
            ],
            providers: [
                { provide: ComponentFixtureAutoDetect, useValue: true },
                { provide: OptionsService, useValue: optionServiceMock },
            ],
            declarations: [EventLogFilterComponent],
            schemas: [NO_ERRORS_SCHEMA]
        }).compileComponents();
    }));
    
    beforeEach(() => {
        fixture = TestBed.createComponent(EventLogFilterComponent);
        component = fixture.componentInstance;
        optionsService = TestBed.get(OptionsService);
        component.filterElem = jasmine.createSpyObj('filterElem', ['close']);
        fixture.detectChanges();
    });
    

    和具体问题并没有太大关系,但我是通过谷歌搜索同样的错误登陆这里的,所以我将分享我的解决方法。问题是我在
    fixture.whenStable()内调用
    fixture.detectChanges()
    ,然后(()=>{})
    而没有将测试包装到
    async
    函数中

    之前:

    it('should...', () => {
      fixture.whenStable().then(() => {
        fixture.detectChanges();
      });
    });
    
    之后:


    这个答案对我没有帮助。我找到了其他解决办法

    子组件具有在单击“关闭”按钮时激发的输出

    <child-component
        *ngIf="childComponentIsShown"
        (formCloseEmitter)="hideChildComponent()"
    ></child-component>
    

    希望这会对某人有所帮助。

    我的解决方案是取消所有观察员的订阅

    订阅:

    ngOnInit() {
         this._currentUserSubscription = this._auth.currentUser.subscribe(currentUser => {});
    }
    
    取消对changeDetector.detach()的订阅:

    这对我的代码是必要的,我还必须使用ChangeDetectorRef功能,只有这两件事我的代码没有错误。

    简单:

    import { OnDestroy } from '@angular/core';
    import { Subject } from 'rxjs/Subject';
    
    export class Component implements OnDestroy {
        componentDestroyed: Subject<boolean> = new Subject();
    
    constructor() { }
    
    function() {
       this.service.serviceFunction
         .takeUntil(this.componentDestroyed)
         .subscribe((incomingObservable: Type) => {
           this.variable = incomingObservable;
         });
      }
    
    ngOnDestroy() {
       this._cdRef.detach(); //If you use change dectector
       this.componentDestroyed.next(true);
       this.componentDestroyed.complete();
    }
    
    从'@angular/core'导入{OnDestroy};
    从'rxjs/Subject'导入{Subject};
    导出类组件实现OnDestroy{
    componentDestroyed:主题=新主题();
    构造函数(){}
    函数(){
    this.service.serviceFunction
    .takeUntil(此.component已销毁)
    .subscribe((incomingObservable:Type)=>{
    该变量=不可观测;
    });
    }
    恩贡德斯特罗(){
    这是.\u cdRef.detach();//如果使用change Detector
    this.componentDestroyed.next(true);
    此.componentDestroyed.complete();
    }
    
    我用以下方法解决了这个问题:

    if (!(<ViewRef>this.cd).destroyed) {
       this.cd.detectChanges();
    }
    
    if(!(this.cd).已销毁){
    this.cd.detectChanges();
    }
    
    我的原因发生在我试图用NgbActiveModal打开一个模式对话框时。显然,从自己的
    ngOnInit()
    调用
    .disease()
    会导致这种情况

    export class MyModal {
        constructor(private modalInstance: NgbActiveModal) {
        }
    
        ngOnInit() {
           if (foo) this.modalInstance.dismiss();
        }
    
    解决办法是在解雇前等一等


    if(foo)setTimeout(()=>this.modalInstance.disease());

    对我来说,唯一有效的解决方案是:

    ngOnInit() {
        if (this.destroyedComponent) this.changeDetector.reattach();
    
    this.destroyedComponent = false;
    this.subscription = this.reactive.channel$.subscribe(msg => {
      switch (msg) {
        case "config:new_data":
          if (!this.destroyedComponent) {
            this.table.initTable();
            this.changeDetector.detectChanges();
          }
      }
    })
    }
    
    ngOnDestroy() {
       this.subscription = null;
       this.destroyedComponent = true;
       this.changeDetector.detach();
    }
    
    说明:

  • 如果部件先前已损坏,则重新连接探测器
  • 将上一个标志设置为falsy值
  • 保存RxJs订阅,并在其中设置所需的逻辑
  • 将该逻辑包装在一个条件中,该条件检查组件是否已被先前声明的标志设置为已销毁
  • 对该块内的更改执行所需的检测
  • 设置ngondestory()方法并使订阅无效,将destroyedComponent标志设置为truthy值,然后分离changeDetector

  • 只需在OnDestroy生命周期挂钩上分离ChangeDetectorRef,并在执行detectChanges方法之前检查ChangeDetectorRef是否已销毁

        constructor(private cd: ChangeDetectorRef){}
    
        someFunction(){
          if(!this.cd['destroyed']){
            this.cd.detectChanges();
          }
        }
    
        ngOnDestroy(){
          this.cd.detach();
        }
    

    要避免此错误,请尝试通过以下方式包装模型更改代码,而不是调用detectChanges():

    this.ngZone.run(() => {
          ...
    });
    

    注释detectChanges();函数的调用,并检查其在何处生成其他错误我在同一场景中也有同样的问题。当我这样做时,我在ngOnDestory函数:console.js:26 error error:Uncaught(承诺中)中得到了这个错误:TypeError:无法读取未定义TypeError的属性'detach':无法读取未定义TypeError的属性'detach'。这意味着您的
    ChangeDetectorRef
    服务名称可能不正确?如果构造函数中有
    private cdRef:ChangeDetectorRef
    ,则该方法应该工作。为什么(
    detectChanges
    )会被禁用
    ngOnInit() {
        if (this.destroyedComponent) this.changeDetector.reattach();
    
    this.destroyedComponent = false;
    this.subscription = this.reactive.channel$.subscribe(msg => {
      switch (msg) {
        case "config:new_data":
          if (!this.destroyedComponent) {
            this.table.initTable();
            this.changeDetector.detectChanges();
          }
      }
    })
    }
    
    ngOnDestroy() {
       this.subscription = null;
       this.destroyedComponent = true;
       this.changeDetector.detach();
    }
    
        constructor(private cd: ChangeDetectorRef){}
    
        someFunction(){
          if(!this.cd['destroyed']){
            this.cd.detectChanges();
          }
        }
    
        ngOnDestroy(){
          this.cd.detach();
        }
    
    this.ngZone.run(() => {
          ...
    });