我对angular还很陌生,目前正在使用它构建一个web应用程序.我的问题在于,当一个组件中的值在另一个组件中被更改后,两个组件中的值都是不相关的.为了实现这一点,我试图使用一个订阅不工作.
我的根组件的html(app.component.html)看起来像这样:
<app-navbar></app-navbar>
<router-outlet></router-outlet>
在router-outlet 内,用户被自动重定向到登录页面(每个页面都是一个组件),除非服务器设置和验证了用户ID和令牌.一旦用户ID和令牌被设置并存储为Cookie,我希望在我的导航栏中显示一个注销按钮.
Navbar.Component.html:
<nav class="bg-dark border-bottom border-body" data-bs-theme="dark">
<a routerLink="">Home</a>
<button *ngIf="isAuthenticated" routerLink="login" class="logout">Log out</button>
</nav>
-Navbar.Component.ts:
import { Component, OnDestroy, OnInit } from '@angular/core';
import { AuthService } from '../auth.service';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-navbar',
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.scss']
})
export class NavbarComponent implements OnInit, OnDestroy {
isAuthenticated: boolean = false
authSubscription: Subscription
constructor(private authService: AuthService) {
}
ngOnInit(): void {
this.authSubscription = this.authService.isAuthenticated$.subscribe((isAuthenticated) =>
{
this.isAuthenticated = isAuthenticated
}
)
}
ngOnDestroy(): void {
this.authSubscription.unsubscribe()
}
}
我正在使用auth.service.ts对用户进行身份验证:
import { Injectable } from '@angular/core';
import { CookieService } from 'ngx-cookie-service';
import { AUTHENTICATE } from './graphql/graphql.queries';
import { Apollo } from 'apollo-angular';
import { BehaviorSubject, Observable, firstValueFrom } from 'rxjs';
@Injectable({
providedIn: "root",
})
export class AuthService {
isAuthenticated = false;
error: any
private isAuthenticatedBS = new BehaviorSubject<boolean>(this.isAuthenticated)
public isAuthenticated$ : Observable<boolean> = this.isAuthenticatedBS.asObservable()
constructor(private cookieService: CookieService, private apollo: Apollo) {
this.checkAuthentication()
}
async checkAuthentication(): Promise<boolean> {
this.isAuthenticated = await this.authenticate()
return this.isAuthenticated;
}
async authenticate()
{
if(this.cookieService.get("userId") && this.cookieService.get("token"))
{
const response = await firstValueFrom(this.apollo.query({
query: AUTHENTICATE,
variables: {
userId: +this.cookieService.get("userId"),
},
fetchPolicy: 'network-only',
}));
if(<number>(<any>response.data).authenticate != null)
{
if(<number>(<any>response.data).authenticate.id > 0)
{
return true
}
}
return false
}
else
{
return false
}
}
}
问题是Navbar.Component.ts中的"isAuthenticated"属性似乎从未更新过.
What I've tried and expected个
应该发生的是,一旦我用正确的邮箱和密码登录,我会收到一个令牌,并将令牌和用户ID存储为Cookie(这部分肯定有效),然后被重定向到主页.每次用户try 导航到需要身份验证的页面时,Auth.Guard都会调用auth.service的判断身份验证方法,以判断具有给定ID和令牌的用户是否存在.登录后,注销按钮应该出现在导航栏中,并一直保持到用户决定注销并删除存储用户ID和令牌的Cookie.
我try 手动触发更改检测,并使用控制台日志(log)判断身份验证是否成功.根据chatgpt的建议,如果你想了解更多关于组件状态变化的细节,我已经为chrome安装了angular devtools扩展.
以下是angular devtools向我展示的一个小概述: app-navbar's properties as shown in angular devtools