ExpressionChangedAfterItHasBeenCheckedError:无法检测 [英] ExpressionChangedAfterItHasBeenCheckedError:Unable to detect

查看:71
本文介绍了ExpressionChangedAfterItHasBeenCheckedError:无法检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个4号角的应用程序.

I have a angular 4 application.

app.component.html 看起来像这样

<!--The content below is only a placeholder and can be replaced.-->
<loading-bar color="#FF0000" [height]="3" [animationTime]="0.3" [runInterval]="100" [progress]="0"></loading-bar>
<div class="app app-header-fixed" value="test">
    <app-header *ngIf="header" name="app_header"></app-header>

    <app-left-menu *ngIf="leftmenu" name="app_leftMenu"></app-left-menu>
    <div id="content" class="app-content abc_plain_wraper" role="main">
        <router-outlet></router-outlet>
    </div>

    <app-right-menu *ngIf="rightmenu"  name="app_rightMenu"></app-right-menu>

</div>

基本上,在登录时,它们是隐藏的;在成功登录后,它们在注销时再次可见,它们是隐藏的.

Basically on Login they are hidden and after successful login they are visible again on logout they are hidden.

为此,我有一个mange_component服务,该服务会在标题,右键菜单和左菜单的值更改时发出一个事件.

For this i have a mange_component service which emits a event on change in value of the header,rightmenu and left menu.

管理组件服务方法

     import { Component, NgModule, VERSION, Injectable, Output, EventEmitter} from '@angular/core';
import { ComponentStatus } from '../model/component-status';
import { Observable } from 'rxjs/Rx';



@Injectable()
export class ManageComponentStatusService {
    @Output() OnChange: EventEmitter<any> = new EventEmitter();
    @Output() ManageHeader: EventEmitter<any> = new EventEmitter();

    componentStatus: any;

    constructor() {
        this.componentStatus = new ComponentStatus();
        this.componentStatus.header = false;
        this.componentStatus.leftMenu = false;
        this.componentStatus.rightMenu = false;
        this.componentStatus.plainHeader = true;
    }

    public setComponentStatus(header: any, left: any, right: any) {

        this.componentStatus.header = header;
        this.componentStatus.leftMenu = left;
        this.componentStatus.rightMenu = right;
        this.OnChange.emit(this.componentStatus);
    }

    public getComponentStatus(): Observable<any> {
        return this.OnChange;
    }

    public setPlainHeader(status:any) {

        this.componentStatus.plainHeader = status;
        var self = this;
        setTimeout(function () {
            self.ManageHeader.emit(self.componentStatus.plainHeader);
        }, 300);


    }

    public restoreHeader() {
        this.componentStatus.plainHeader = true;
    }

    public getHeaderStatus(): Observable<any>{
        return this.ManageHeader;
    }

}

在app.component.ts中,我们设置了组件值,并且还具有订阅以检查更改

In the app.component.ts we set the component value and also have a subscribe to check the changes

 export class AppComponent implements OnInit {

    title = 'test App';
    authSettings: any;
    appConstants: any;
    _router: any;
    header: any=false;
    leftmenu: any=false;
    rightmenu: any=false;
    compModel: any;


    constructor(private ngAuthService: NgAuthService, private tenantServ: TenantService,
        private loadingBarService: LoadingBarService, private router: Router,
        public manageComp: ManageComponentStatusService,public socialServ: SocialMediaSettingsService) {

        this._router = router;        
        this.authSettings = ngAuthService.getNgAuth();
        this.appConstants = ngAuthService.getAppConstant();
        //this.manageComp.setComponentStatus(false, false, false);


        router.events.subscribe(event => {
            if (event instanceof NavigationStart) {
                this.loadingBarService.start();
                //console.log("navigation start");
            }
            else if (event instanceof NavigationEnd) {

                //console.log("navigation end");
                this.loadingBarService.complete();
            }


        });

        this.compModel = this.manageComp.getComponentStatus();

    }


    logOut() {
        this.manageComp.setComponentStatus(false, false, false);
        this._router.navigate(['login']);

    }

    ngOnInit() {

        //this.header = this.compModel.header;
        //this.leftmenu = this.compModel.leftMenu;
        //this.rightmenu = this.compModel.rightMenu;
        this._router.navigate(['login']);
        /*subscribing to change*/
        this.manageComp.getComponentStatus().subscribe(
            data => {
                this.header = data.header;
                this.leftmenu = data.leftMenu;
                this.rightmenu = data.rightMenu;
            });



    }
    ngOnChanges() {
        alert("change detected");
    }



}

成功登录后,加载的路由为abc 以下是abc组件.我仅添加相关部分

after successful login the route loaded is abc Below is the abc component .I'm adding only the relevant part

ngOnInit() {

        this.compStatus.setComponentStatus(true, true, true);//UPDATING HERE
        this.userServ.setUserProfile();
        this.compStatus.setPlainHeader(true);
        this.opts = {
            barBackground: '#C9C9C9',
            gridBackground: '#D9D9D9',
            barBorderRadius: '1',
            barWidth: '2',
            gridWidth: '1'
        };
        this.socialMediaData = this.socialSetServ.getSocialProvider();
        this.isContentEditable = this.commonServ.getAppConfig().contentEditable;        

    }

当登录页面加载时,我会收到此异常.

when the login page loads i get this exception.

ng:///AppModule/AppComponent.ngfactory.js:40错误错误: ExpressionChangedAfterItHasBeenCheckedError:表达式已更改 经过检查后.上一个值:未定义".当前值: 假".

ng:///AppModule/AppComponent.ngfactory.js:40 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'undefined'. Current value: 'false'.

我知道我与变更检测有关系,但不知道如何纠正.

i know i had something to do with change detaction ,but have no idea how to correct this.

推荐答案

发生此错误是因为变量的值之前已更改 更改检测可以在前一个上运行.

This error happens because the value of the variable changed before change Detection can work on the previous one.

一种解决方法是使用setTimeout函数安排一个 然后,宏任务将在下一个VM回合中执行.

A work around for this is to use The setTimeout function schedules a macrotask then will be executed in the following VM turn.

您可以将此代码this.compStatus.setComponentStatus(true, true, true);放在set Timeout

setTimeout(() => {
    this.compStatus.setComponentStatus(true, true, true);
}, 0);

这篇关于ExpressionChangedAfterItHasBeenCheckedError:无法检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆