我看到有很多关于这个主题的帖子,但大多与异步服务调用有关。我有一个应用程序组件负责登录到 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/