首页 > 解决方案 > Angular 路由保持显示前一个组件并且不会完全加载下一个

问题描述

我有一个组件,它是一个动态生成的角度表,必须显示在“表”路径中。但首先,该应用程序在“身份验证”页面上启动,这是我的登录页面。如果身份验证正确,我会被重定向到 /table 没问题,但是:1)仍然显示身份验证组件 2)未加载表,未调用 ngOnInit(),似乎没有加载任何 ts 代码,只是基本的html。

如果我禁用canActivate(),它不会改变任何东西,但如果我将routerLink放到auth组件中的/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;
  }
  
}

标签: angulartypescriptroutingangular-routing

解决方案


你正在走出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']);
  }); 
});

推荐阅读