Angular 路由保持显示上一个组件并且不完全加载下一个
Angular routing keeps previous component displayed and doesn't fully load the next one
我有一个动态生成的组件 angular table 必须显示在 'table' 路径。但首先,应用程序在 'auth' 页面上启动,这是我的登录页面。如果身份验证正确,我会重定向到 /table 没问题,但是:
1)仍然显示auth组件
2) table 未加载,未调用 ngOnInit(),似乎加载了 ts 代码的 none,只是基本的 html.
如果我禁用 canActivate(),它不会改变任何东西,但如果我在 auth 组件中将 routerLink 放到 /table,一切正常...
这可能与我的身份验证方式 (GoogleAuth) 有关,因此,这是一些代码,尽管我不确定它是否有用..
auth.component.ts
import { Component, OnInit, ViewChild, ElementRef} from '@angular/core';
import { AuthService } from '../../services/auth.service';
import { Router } from '@angular/router';
@Component({
selector: 'app-auth',
templateUrl: './auth.component.html',
styleUrls: ['./auth.component.scss']
})
export class AuthComponent implements OnInit {
constructor(private authService: AuthService, private router: Router){}
auth2: any;
@ViewChild('loginRef', {static: true }) loginElement: ElementRef;
ngOnInit() {
this.googleSDK();
}
prepareLoginButton() {
this.auth2.attachClickHandler(this.loginElement.nativeElement, {},
(googleUser) => {
//ici, l'utilisateur est authentifié
let profile = googleUser.getBasicProfile();
console.log('Token || ' + googleUser.getAuthResponse().id_token);
console.log('ID: ' + profile.getId());
console.log('Name: ' + profile.getName());
console.log('Image URL: ' + profile.getImageUrl());
console.log('Email: ' + profile.getEmail());
// YOUR CODE HERE
this.authService.isAuth = true;
this.router.navigate(['/table']);
}, (error) => {
alert(JSON.stringify(error, undefined, 2));
});
}
googleSDK() {
window['googleSDKLoaded'] = () => {
window['gapi'].load('auth2', () => {
this.auth2 = window['gapi'].auth2.init({
client_id: '88179289847-pcj5c8u563k4igvqof1k65tcbqu4q97f.apps.googleusercontent.com',
cookie_policy: 'single_host_origin',
scope: 'profile email'
});
this.prepareLoginButton();
});
}
console.log("google sdk");
(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "https://apis.google.com/js/platform.js?onload=googleSDKLoaded";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'google-jssdk'));
}
}
auth.guard.ts
import { Injectable, OnInit } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService} from '../services/auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
ngOnInit(){
}
constructor (private authService: AuthService, private router: Router){}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if(this.authService.isAuth){
return true;
}
else{
this.router.navigate(['/auth']);
}
return true;
}
}
您正跨出 NgZone
。 this.auth2.attachClickHandler
的回调不再在区域中,因此在路由时不再进行变化检测。您应该更新您的代码以使用 ngZone.run()
:
重新进入该区域
constructor(
private authService: AuthService,
private router: Router,
private ngZone: NgZone
){}
this.auth2.attachClickHandler(this.loginElement.nativeElement, {}, (googleUser) => {
this.ngZone.run(() => {
// ...
this.router.navigate(['/table']);
});
});
我有一个动态生成的组件 angular table 必须显示在 'table' 路径。但首先,应用程序在 'auth' 页面上启动,这是我的登录页面。如果身份验证正确,我会重定向到 /table 没问题,但是: 1)仍然显示auth组件 2) table 未加载,未调用 ngOnInit(),似乎加载了 ts 代码的 none,只是基本的 html.
如果我禁用 canActivate(),它不会改变任何东西,但如果我在 auth 组件中将 routerLink 放到 /table,一切正常...
这可能与我的身份验证方式 (GoogleAuth) 有关,因此,这是一些代码,尽管我不确定它是否有用..
auth.component.ts
import { Component, OnInit, ViewChild, ElementRef} from '@angular/core';
import { AuthService } from '../../services/auth.service';
import { Router } from '@angular/router';
@Component({
selector: 'app-auth',
templateUrl: './auth.component.html',
styleUrls: ['./auth.component.scss']
})
export class AuthComponent implements OnInit {
constructor(private authService: AuthService, private router: Router){}
auth2: any;
@ViewChild('loginRef', {static: true }) loginElement: ElementRef;
ngOnInit() {
this.googleSDK();
}
prepareLoginButton() {
this.auth2.attachClickHandler(this.loginElement.nativeElement, {},
(googleUser) => {
//ici, l'utilisateur est authentifié
let profile = googleUser.getBasicProfile();
console.log('Token || ' + googleUser.getAuthResponse().id_token);
console.log('ID: ' + profile.getId());
console.log('Name: ' + profile.getName());
console.log('Image URL: ' + profile.getImageUrl());
console.log('Email: ' + profile.getEmail());
// YOUR CODE HERE
this.authService.isAuth = true;
this.router.navigate(['/table']);
}, (error) => {
alert(JSON.stringify(error, undefined, 2));
});
}
googleSDK() {
window['googleSDKLoaded'] = () => {
window['gapi'].load('auth2', () => {
this.auth2 = window['gapi'].auth2.init({
client_id: '88179289847-pcj5c8u563k4igvqof1k65tcbqu4q97f.apps.googleusercontent.com',
cookie_policy: 'single_host_origin',
scope: 'profile email'
});
this.prepareLoginButton();
});
}
console.log("google sdk");
(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "https://apis.google.com/js/platform.js?onload=googleSDKLoaded";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'google-jssdk'));
}
}
auth.guard.ts
import { Injectable, OnInit } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService} from '../services/auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
ngOnInit(){
}
constructor (private authService: AuthService, private router: Router){}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if(this.authService.isAuth){
return true;
}
else{
this.router.navigate(['/auth']);
}
return true;
}
}
您正跨出 NgZone
。 this.auth2.attachClickHandler
的回调不再在区域中,因此在路由时不再进行变化检测。您应该更新您的代码以使用 ngZone.run()
:
constructor(
private authService: AuthService,
private router: Router,
private ngZone: NgZone
){}
this.auth2.attachClickHandler(this.loginElement.nativeElement, {}, (googleUser) => {
this.ngZone.run(() => {
// ...
this.router.navigate(['/table']);
});
});