2017-10-12 123 views
1

我有一個角度爲4的應用程序。ExpressionChangedAfterItHasBeenCheckedError:無法檢測

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> 

基本上在登錄他們是隱藏的,成功登錄後,他們再次上可以看到註銷它們是隱藏的。

爲此,我有一個mange_component服務,它會在標題,右鍵菜單和左菜單的值發生變化時發出事件。

管理組件服務方法

 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,也有一個訂閱檢查變化

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組件。我只添加相關部分

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;   

    } 

當登錄頁面加載時,我得到這個異常。

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

我知道我與改變的部分有關,但不知道如何改正這一點。

+0

它在哪裏,你從真正改變變量設置爲false? –

+0

登錄後加載的頁面 ngOnInit(){this.compStatus.setComponentStatus(true,true,true);} –

+0

你可以在這裏添加代碼嗎? –

回答

0

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

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); 
+0

謝謝這工作。 –