登录页面后 Angular 未刷新最新信息

问题描述 投票:0回答:2

我正在 Angular 中创建我的第一次登录。一切正常,用户已登录,并且他被重定向到 GiveDashboardComponent 并在导航栏上显示而不是“登录”按钮 - 显示“注销”,注销时则相反。问题是,只有当我手动刷新页面时,这些更改才会出现在我面前(这就是我知道它的工作原理)。在 Angular 中正确的做法是什么,或者我在当前代码中选择了一些错误的方法?

我的登录组件:

export class LoginComponent implements OnInit {
  user: User = new User();
  errorMessage: string = '';

  constructor(
    private authService: AuthenticationService,
    private router: Router,
    public sharedService: SharedService
  ) {}

  ngOnInit(): void {
    if (this.authService.currentUserValue?.id) {
      this.router.navigate(['/give-dashboard']);
    }
  }

  exit() {
    this.sharedService.showLoginComponent = false;
  }

  login() {
    this.authService.login(this.user).subscribe(
      (data) => {
        this.router.navigate(['/give-dashboard']);
      },
      (err) => {
        this.errorMessage = 'Username or password is incorrect.';
        console.log(err);
      }
    );
  }
}

导航栏组件:

export class NavBarComponent implements OnInit {
  isLoggedIn = false;
  user: User = new User();

  constructor(
    private router: Router,
    private authService: AuthenticationService,
    private sharedService: SharedService
  ) {}

  ngOnInit(): void {
    this.authService.loggedUser.subscribe((res) => {
      if (res) {
        this.isLoggedIn = true;
      } else {
        this.isLoggedIn = false;
      }
    });
  }
  showLogin() {
    this.sharedService.showLoginComponent = true;
  }

  logout() {
    this.authService.logout();
    this.router.navigate(['']);
    this.isLoggedIn = false;
  }
}

还有仪表板组件(我尝试简单地进行导航,但这显然不是方法)

export class GiveDashboardComponent implements OnInit {
  constructor(private router: Router) {}

  ngOnInit(): void {
    this.router.navigate(['/give-dashboard']);
  }
}

和身份验证服务:

export class AuthenticationService {
  public currentUser: Observable<User>;
  private currentUserSubject: BehaviorSubject<User>;
  private isLoggedIn = new BehaviorSubject<boolean>(this.userIsLoggedIn());
  public loggedUser = this.isLoggedIn.asObservable();

  constructor(private http: HttpClient) {
    let storageUser;
    const storageUserAsStr = localStorage.getItem('currentUser');
    if (storageUserAsStr) {
      storageUser = JSON.parse(storageUserAsStr);
    }
    this.currentUserSubject = new BehaviorSubject<User>(storageUser);
    this.currentUser = this.currentUserSubject.asObservable();
  }

  public get currentUserValue(): User {
    return this.currentUserSubject.value;
  }

  login(user: User): Observable<any> {
    return this.http.post<User>(API_URL + '/sign-in', user).pipe(
      map((res) => {
        if (res) {
          // set session-user
          this.setSessionUser(res);
        } else {
          return false;
        }
        return res;
      })
    );
  }

  register(user: User): Observable<any> {
    return this.http.post<User>(API_URL + '/sign-up', user).pipe(
      map((res) => {
        if (res) {
          this.setSessionUser(res);
        } else {
          return false;
        }
        return res;
      })
    );
  }

  setSessionUser(user: User) {
    localStorage.setItem('currentUser', JSON.stringify(user));
    this.currentUserSubject.next(user);
  }

  logout() {
    localStorage.removeItem('currentUser');
    this.currentUserSubject.next(new User());
    // this.currentUserSubject.next(null);
  }
  refreshToken(): Observable<any> {
    return this.http.post(
      API_URL + '/refresh-token?token=' + this.currentUserValue?.refreshToken,
      {}
    );
  }

  userIsLoggedIn() {
    return !!localStorage.getItem('currentUser');
  }
}

angular typescript
2个回答
0
投票

这个问题看起来像是changeDetection有问题。我会选择 RxJS 库中的 Observable 和 subject。这允许组件订阅更改并相应更新。您可以在 AuthenticationService 中使用BehaviorSubject 来保存用户的当前状态。

认证服务示例:

 export class AuthenticationService {
  private currentUserSubject: BehaviorSubject<User | null>;
  public currentUser$: Observable<User | null>;

  constructor(private http: HttpClient) {
    let storageUser: User | null = null;
    const storageUserAsStr = localStorage.getItem('currentUser');
    if (storageUserAsStr) {
      storageUser = JSON.parse(storageUserAsStr);
    }
    this.currentUserSubject = new BehaviorSubject<User | null>(storageUser);
    this.currentUser$ = this.currentUserSubject.asObservable();
  }

  setSessionUser(user: User) {
    localStorage.setItem('currentUser', JSON.stringify(user));
    this.currentUserSubject.next(user);
  }

  logout() {
    localStorage.removeItem('currentUser');
    this.currentUserSubject.next(null);
  }
  // ... remaining code
}

并在您的 NavBarComponent 中,订阅 currentUser:

NavBarComponent 的 TS.组件:

export class NavBarComponent implements OnInit {
  isLoggedIn = false;

  constructor(
    private router: Router,
    private authService: AuthenticationService,
    private sharedService: SharedService
  ) {}

  ngOnInit(): void {
    this.authService.currentUser$.subscribe((user) => {
      this.isLoggedIn = !!user;
    });
  }

  // ... remaining code
}

在这种方法中,每当用户的状态发生变化(登录或注销)时,AuthenticationService 都会更新其 currentUserSubject,然后将更改发送给其所有订阅者。


0
投票

对我来说,我只是保持非常简单,如果这是我的代码,我将添加这个简单的代码 位置.reload();这里=>

login() {
    this.authService.login(this.user).subscribe(
      (data) => {

// add it here and thank me later :)
        location.reload()
        this.router.navigate(['/give-dashboard']);
      },
      (err) => {
        this.errorMessage = 'Username or password is incorrect.';
        console.log(err);
      }




// and of course also here 

 ngOnInit(): void {
    if (this.authService.currentUserValue?.id) {
 
location.reload()
      this.router.navigate(['/give-dashboard']);
    }
  }
© www.soinside.com 2019 - 2024. All rights reserved.