Angular 路由更改时不执行绑定、指令和 ngOnInit
Angular does not execute bindings, directive and ngOnInit when route change
在我的应用程序中,我遇到了 Angular 未绑定属性的问题。它也不调用 ngOnInit
和 ngAfterViewInit
或执行指令。
这是部分 LoginComponent 代码:
@Component({
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit
//.....
public test: string = 'some dummy test';
constructor(
private cd: ChangeDetectorRef,
private fb: FormBuilder, private router: Router, private route: ActivatedRoute,
private authService: AuthService,
private usersService: UserService,
private notificationsService: NotificationsService
)
{
this.loginForm = fb.group({
email: ["", Validators.required],
password: ["", Validators.required]
});
console.info("constructor");
}
ngOnInit()
{
console.info("ngOnInit");
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
}
ngAfterViewInit()
{
this.initGapi();
console.info("afterviewinit");
}
奇怪的是,这在我打开页面或 HMR 刷新页面时有效,但在我登录和注销时无效。
这是注销代码:
logout(): boolean
{
this.authService.logout();
}
//authservice.ts
logout()
{
localStorage.removeItem("token");
localStorage.removeItem("refresh_token");
localStorage.removeItem("profile");
if (gapi.auth2)
{
const instance = gapi.auth2.getAuthInstance();
if (instance)
{
instance.signOut().then(() =>
{
this.router.navigate(["login"]);
});
return;
}
}
this.router.navigate(["login"]);
}
我注销和未绑定时的区别是:
按钮没有样式。这应该执行 kendoButton
指令 <button class="center" kendoButton type="submit">
缺少测试绑定(一些虚拟测试)
ngOnInit
和 ngAfterViewInit
未被调用。
控制台没有错误。我还录制屏幕(它从空白页开始)。我有最新的 Chrome 和 Firefox,这两种浏览器都有同样的问题。
有没有人知道哪里出了问题或者我还能尝试什么?
问题出在 Google gapi 库中:
const instance = gapi.auth2.getAuthInstance();
if (instance)
{
instance.signOut().then(() =>
{
this.router.navigate(["login"]); //This is runned outside Angular's context.
});
return;
}
instance.signOut
的回调在 Angular 的上下文之外运行。
解决方案是将导航放在 google.gapi
回调之外:
const instance = gapi.auth2.getAuthInstance();
if (instance)
{
instance.signOut();
this.router.navigate(["login"]);
}
或者,如果您希望在从 Google 注销后导航,请使用区域。 This 可能会有帮助。
如果 gapi
运行 在 Angulars 区域之外,则更改检测不会通知 运行。您可以 运行 在 Angulars 区域中显式编码,例如
constructor(private zone:NgZone) {}
...
this.zone.run(() => {
this.router.navigate(["login"])
});
在我的应用程序中,我遇到了 Angular 未绑定属性的问题。它也不调用 ngOnInit
和 ngAfterViewInit
或执行指令。
这是部分 LoginComponent 代码:
@Component({
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit
//.....
public test: string = 'some dummy test';
constructor(
private cd: ChangeDetectorRef,
private fb: FormBuilder, private router: Router, private route: ActivatedRoute,
private authService: AuthService,
private usersService: UserService,
private notificationsService: NotificationsService
)
{
this.loginForm = fb.group({
email: ["", Validators.required],
password: ["", Validators.required]
});
console.info("constructor");
}
ngOnInit()
{
console.info("ngOnInit");
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
}
ngAfterViewInit()
{
this.initGapi();
console.info("afterviewinit");
}
奇怪的是,这在我打开页面或 HMR 刷新页面时有效,但在我登录和注销时无效。
这是注销代码:
logout(): boolean
{
this.authService.logout();
}
//authservice.ts
logout()
{
localStorage.removeItem("token");
localStorage.removeItem("refresh_token");
localStorage.removeItem("profile");
if (gapi.auth2)
{
const instance = gapi.auth2.getAuthInstance();
if (instance)
{
instance.signOut().then(() =>
{
this.router.navigate(["login"]);
});
return;
}
}
this.router.navigate(["login"]);
}
我注销和未绑定时的区别是:
按钮没有样式。这应该执行
kendoButton
指令<button class="center" kendoButton type="submit">
缺少测试绑定(一些虚拟测试)
ngOnInit
和ngAfterViewInit
未被调用。
控制台没有错误。我还录制屏幕(它从空白页开始)。我有最新的 Chrome 和 Firefox,这两种浏览器都有同样的问题。
有没有人知道哪里出了问题或者我还能尝试什么?
问题出在 Google gapi 库中:
const instance = gapi.auth2.getAuthInstance();
if (instance)
{
instance.signOut().then(() =>
{
this.router.navigate(["login"]); //This is runned outside Angular's context.
});
return;
}
instance.signOut
的回调在 Angular 的上下文之外运行。
解决方案是将导航放在 google.gapi
回调之外:
const instance = gapi.auth2.getAuthInstance();
if (instance)
{
instance.signOut();
this.router.navigate(["login"]);
}
或者,如果您希望在从 Google 注销后导航,请使用区域。 This 可能会有帮助。
如果 gapi
运行 在 Angulars 区域之外,则更改检测不会通知 运行。您可以 运行 在 Angulars 区域中显式编码,例如
constructor(private zone:NgZone) {}
...
this.zone.run(() => {
this.router.navigate(["login"])
});