更改路由时行为主题变为空
Behavior Subject Becomes Null When Changing routes
我正在尝试设置检查以确保用户在我的 header 组件中经过身份验证,以便访问仅供登录用户使用的路由。该部分有效,但是当我在登录后尝试使用其中一条路线时,它会将我的用户行为主题更改回 null,从而也呈现我的 isAuthenticated false。我不确定这里发生了什么,因为我也没有收到错误。
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { BehaviorSubject, Subject } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { User } from '../models/user.model';
interface LoginData {
first_name?: string;
last_name?: string;
email?: string;
password?: string;
}
@Injectable({
providedIn: 'root',
})
export class AuthService {
apiUrl = 'http://localhost:3000/api/v1/users/';
tokenExp: Date = new Date();
user = new BehaviorSubject<User | null>(null);
constructor(private http: HttpClient, private router: Router) {}
login(form: LoginData) {
return this.http.post(this.apiUrl + 'login', form).pipe(
map((res: any) => {
const user = res;
console.log(user);
if (user.success) {
localStorage.setItem('Bearer', user.payload.token.value);
const newUser = new User(
user.payload.user.email,
user.payload.user.first_name,
user.payload.user.last_name,
user.payload.user.blogs,
user.payload.user.id,
user.payload.token
);
this.user.next(newUser);
}
})
);
}
.
.
.
}
以上是我的身份验证服务,我将用户设置为我的行为主题。
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { AuthService } from 'src/app/auth/services/auth.service';
@Component({
selector: 'app-navigation',
templateUrl: './navigation.component.html',
styleUrls: ['./navigation.component.scss'],
})
export class NavigationComponent implements OnInit, OnDestroy {
isAuthenticated: boolean = false;
private userSub: Subscription;
constructor(private authService: AuthService) {
this.userSub = this.authService.user.subscribe((user) => {
this.isAuthenticated = !!user;
});
}
ngOnInit(): void {}
onLogout() {
this.authService.logout();
}
ngOnDestroy(): void {
this.userSub.unsubscribe();
}
}
这是我的导航组件,我在其中订阅了该行为主题,如果我的 BS 为 null 则将 isAuthenticated 设置为 false,如果有值则设置为 true。
问题出在我登录后尝试单击任何路线时。单击路线后,它将设置为已验证为 false,而我的用户为 null。出于某种原因,它正在改变我的行为主体的价值,我不知道为什么。
这是导航模板:
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">Sicktastic Blogs</a>
<button
class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNav"
aria-controls="navbarNav"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li
class="nav-item"
routerLink="/home"
routerLinkActive="active"
*ngIf="isAuthenticated"
>
<a class="nav-link" aria-current="page" href="#">HOME</a>
</li>
<li
class="nav-item"
routerLink="/profile"
routerLinkActive="active"
*ngIf="isAuthenticated"
>
<a class="nav-link" aria-current="page" href="#">PROFILE</a>
</li>
<li
class="nav-item"
routerLink="/register"
routerLinkActive="active"
*ngIf="!isAuthenticated"
>
<a class="nav-link">REGISTER</a>
</li>
<li
class="nav-item"
routerLink="/login"
routerLinkActive="active"
*ngIf="!isAuthenticated"
>
<a class="nav-link">LOGIN</a>
</li>
<li class="nav-item" *ngIf="isAuthenticated">
<a class="nav-link" (click)="onLogout()">LOGOUT</a>
</li>
</ul>
</div>
</div>
</nav>
问题是您的 link 中有 href="#"
导致您的页面在您转到 link 时重新加载,进而导致组件的状态重置.
您的 routerLink 指令需要在您的 anchor 元素上进行,而不是列表项。如果需要,您可以将 RouterLinkActive 指令保留在父元素上,因为如果任何后代路由器 link 处于活动状态,它将被拾取。
您似乎在使用 Bootstrap?如果 link 没有占用其父级的整个宽度是一个问题,则使用 stretched-link class.
<li class="nav-item" *ngIf="!isAuthenticated" routerLinkActive="active">
<a class="nav-link stretched-link" [routerLink]="['/login']">LOGIN</a>
</li>
我正在尝试设置检查以确保用户在我的 header 组件中经过身份验证,以便访问仅供登录用户使用的路由。该部分有效,但是当我在登录后尝试使用其中一条路线时,它会将我的用户行为主题更改回 null,从而也呈现我的 isAuthenticated false。我不确定这里发生了什么,因为我也没有收到错误。
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { BehaviorSubject, Subject } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { User } from '../models/user.model';
interface LoginData {
first_name?: string;
last_name?: string;
email?: string;
password?: string;
}
@Injectable({
providedIn: 'root',
})
export class AuthService {
apiUrl = 'http://localhost:3000/api/v1/users/';
tokenExp: Date = new Date();
user = new BehaviorSubject<User | null>(null);
constructor(private http: HttpClient, private router: Router) {}
login(form: LoginData) {
return this.http.post(this.apiUrl + 'login', form).pipe(
map((res: any) => {
const user = res;
console.log(user);
if (user.success) {
localStorage.setItem('Bearer', user.payload.token.value);
const newUser = new User(
user.payload.user.email,
user.payload.user.first_name,
user.payload.user.last_name,
user.payload.user.blogs,
user.payload.user.id,
user.payload.token
);
this.user.next(newUser);
}
})
);
}
.
.
.
}
以上是我的身份验证服务,我将用户设置为我的行为主题。
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { AuthService } from 'src/app/auth/services/auth.service';
@Component({
selector: 'app-navigation',
templateUrl: './navigation.component.html',
styleUrls: ['./navigation.component.scss'],
})
export class NavigationComponent implements OnInit, OnDestroy {
isAuthenticated: boolean = false;
private userSub: Subscription;
constructor(private authService: AuthService) {
this.userSub = this.authService.user.subscribe((user) => {
this.isAuthenticated = !!user;
});
}
ngOnInit(): void {}
onLogout() {
this.authService.logout();
}
ngOnDestroy(): void {
this.userSub.unsubscribe();
}
}
这是我的导航组件,我在其中订阅了该行为主题,如果我的 BS 为 null 则将 isAuthenticated 设置为 false,如果有值则设置为 true。
问题出在我登录后尝试单击任何路线时。单击路线后,它将设置为已验证为 false,而我的用户为 null。出于某种原因,它正在改变我的行为主体的价值,我不知道为什么。
这是导航模板:
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">Sicktastic Blogs</a>
<button
class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNav"
aria-controls="navbarNav"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li
class="nav-item"
routerLink="/home"
routerLinkActive="active"
*ngIf="isAuthenticated"
>
<a class="nav-link" aria-current="page" href="#">HOME</a>
</li>
<li
class="nav-item"
routerLink="/profile"
routerLinkActive="active"
*ngIf="isAuthenticated"
>
<a class="nav-link" aria-current="page" href="#">PROFILE</a>
</li>
<li
class="nav-item"
routerLink="/register"
routerLinkActive="active"
*ngIf="!isAuthenticated"
>
<a class="nav-link">REGISTER</a>
</li>
<li
class="nav-item"
routerLink="/login"
routerLinkActive="active"
*ngIf="!isAuthenticated"
>
<a class="nav-link">LOGIN</a>
</li>
<li class="nav-item" *ngIf="isAuthenticated">
<a class="nav-link" (click)="onLogout()">LOGOUT</a>
</li>
</ul>
</div>
</div>
</nav>
问题是您的 link 中有 href="#"
导致您的页面在您转到 link 时重新加载,进而导致组件的状态重置.
您的 routerLink 指令需要在您的 anchor 元素上进行,而不是列表项。如果需要,您可以将 RouterLinkActive 指令保留在父元素上,因为如果任何后代路由器 link 处于活动状态,它将被拾取。
您似乎在使用 Bootstrap?如果 link 没有占用其父级的整个宽度是一个问题,则使用 stretched-link class.
<li class="nav-item" *ngIf="!isAuthenticated" routerLinkActive="active">
<a class="nav-link stretched-link" [routerLink]="['/login']">LOGIN</a>
</li>