angular - 使用 Angular 6 和重定向的 ExpressionChangedAfterItHasBeenCheckedError

标签 angular

我看到有很多关于这个主题的帖子,但大多与异步服务调用有关。我有一个应用程序组件负责登录到 Azure AD。当用户单击登录时,他们将被重定向到 Azure 的登录页面,并被重定向回名为 AuthCallBack 的组件。 AuthCallBack 将调用 AppComponenet 上的一个方法,该方法只设置一个名为 userIsLoggedIn 的 bool 值,我在 ngIf 中使用它。我收到以下错误 ExpressionChangedAfterItHasBeenCheckedError。因为它不是某种 http 异步调用,所以我没有订阅选项,怎么办?

<table>
  <tr>
    <td routerLink="/">Login page</td>
    <td routerLink="/dashboard">Dashboard</td>
    <td (click)="login()">Login</td>
    <td (click)="logout()">Logout</td>
    <td><span *ngIf="userIsLoggedIn">Logged in</span></td>

  </tr>
  <tr>
    <td colspan="5">
       <router-outlet></router-outlet>
    </td>
  </tr>
</table>

应用组件

import { Component,OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { AdalService } from 'adal-angular4';
import { environment } from '../environments/environment';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {

  config = {
    tenant: 'xx-a8b0-4555-97b3-70001a6a7448',
    clientId: 'xx-65b4-4914-905c-aecc3e9197f5',
    redirectUri: "http://localhost:4200/authcallback/",
    logOutUri: "http://localhost:4200",
    postLogoutRedirectUri: "http://localhost:4200",
    endpoints: {
      "http://localhost:63126/": "xx-65b4-4914-905c-aecc3e9197f5"
    }};

  userIsLoggedIn: Observable<boolean>;

  constructor(private adalService: AdalService,private router: Router)
  {
    this.adalService.init(this.config); 
  }

  ngOnInit() {     
  }

  handleWindowCallback()
  {    
    this.adalService.handleWindowCallback();
    this.userIsLoggedIn = this.adalService.userInfo.authenticated;

  }

  login()
  {   
    this.adalService.login();
  }

  logout()
  {
    this.adalService.logOut();
  }
}

授权组件

import { Component, OnInit, NgZone } from '@angular/core';
import { AppComponent } from '../app.component';
import { Router } from '@angular/router';
import { AdalService } from 'adal-angular4';

@Component({
  selector: 'app-auth-callback',
  templateUrl: './authcallback.component.html',
  styleUrls: ['./authcallback.component.css']
})
export class AuthCallbackComponent implements OnInit {

  constructor(private appComponent: AppComponent,private router: Router, private adalService: AdalService, private _zone: NgZone) { }

   ngOnInit() {

    this.appComponent.handleWindowCallback();

    //this.adalService.handleWindowCallback();

    setTimeout(() => {
      this._zone.run(
        () => this.router.navigate(['/'])
      );
    }, 200);
  } 
}

最佳答案

Parent (appComponent) 已经有 CD (change detection) 周期,比子组件改变父组件的状态。在开发模式下 - 另一个 CD 来检查与之前的 CD 周期相比没有任何改变(会抛出错误)。

我们有一个技巧:

-包装在setTimeout中,更改将在新的CD周期中应用。

// AuthComponent
setTimeout(()=>this.appComponent.handleWindowCallback(), 0);

-在父组件中调用ChangeDetectorRef.detectChanges

// AppComponent
constructor(private changeDetectorRef: ChangeDetectorRef){}

handleWindowCallback(){
  /* some code */
  this.changeDetectorRef.detectChanges();
}

关于angular - 使用 Angular 6 和重定向的 ExpressionChangedAfterItHasBeenCheckedError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52436522/

相关文章:

angular - 如何在 Kubernetes 中使用 nginx 连接前端和后端

typescript - 带有来自 ajax 调用的数据的 angular2 Bootstrap

node.js - 如何在 MAC 上安装 Node、npm、Angular cli?

python - JSON 解析错误 - 当我尝试使用 Angular+REST 上传 Excel 工作表时, 'utf-8' 编解码器无法解码位置 XXX 中的字节 0xc9

typescript - 我如何实际部署 Angular 2 + Typescript + systemjs 应用程序?

angular - Angular 中的全局 scss 文件和组件的 scss 文件之间的区别

angular - 如何在 Angular 8 中使用 angular-oauth2-oidc 实现身份验证代码流

angular - 将 PrimeNG 数据表导出为 excel、pdf 和 xml

angular - @ Angular 2 : Better approach Whether to create components or modules

javascript - lodash 按数组 Angular 5 过滤对象数组