我使用 Angular v17 时遇到了一个奇怪的错误,我仍然是一个新手
首先我要开始我的服务,
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { User } from '../../model/user';
import { BehaviorSubject, startWith, tap } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class UserService {
private url = "http://Localhost:8080/"
private currentUserSubject = new BehaviorSubject<string>(JSON.parse(localStorage.getItem('user') || 'null'));
currentUser = this.currentUserSubject.asObservable();
constructor(private http: HttpClient) {
const user = JSON.parse(localStorage.getItem('user') || 'null');
if (user) {
this.currentUserSubject.next(user);
}
}
signup(user: User) {
return this.http.post<User>(`${this.url}Signup`, user).pipe(
tap((response: User) => {
localStorage.setItem('user', JSON.stringify(response.firstName));
this.currentUserSubject.next(response.firstName);
})
)
}
login(user: User) {
return this.http.post<User>(`${this.url}Login`, user).pipe(
tap((response: User) => {
localStorage.setItem('user', JSON.stringify(response.firstName));
this.currentUserSubject.next(response.firstName);
})
)
}
logout() {
localStorage.removeItem('user');
this.currentUserSubject.next('');
}
}
后端工作正常,一切正常,我将用户添加到后端,并将用户名设置为本地存储,
现在的问题是我想从本地存储中获取名称并将其显示在标题中,我在app.component.html中调用它
<app-header></app-header>
<router-outlet></router-outlet>
这是我的 header.component.ts
import { ChangeDetectorRef, Component, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { NavigationEnd, Router, RouterModule } from '@angular/router';
import { UserService } from '../service/user/User.service';
import { CommonModule } from '@angular/common';
import { Observable, filter, switchMap } from 'rxjs';
@Component({
selector: 'app-header',
standalone: true,
imports: [RouterModule, CommonModule],
templateUrl: './header.component.html',
styleUrl: './header.component.css'
})
export class HeaderComponent implements OnInit {
user: string = '';
constructor(private userService: UserService,) { }
ngOnInit(): void {
this.userService.currentUser.subscribe((name) => {
console.log(name)
this.user = name;
});
}
logout(): void {
this.userService.logout();
}
}
这是 console.log 的结果,由于某种原因,名称有一秒钟是空字符串,然后很快就更改为想要的值
现在,当我想根据用户值显示下拉列表以及登录和登录按钮时,只有在重新加载后,下拉列表才显示
这是html的相对部分(我使用新的Angular v17控制流)
@if(!user){<a
class="flex items-center gap-x-2 font-medium text-gray-500 hover:text-blue-600 md:border-s md:border-gray-300 md:my-6 md:ps-6 dark:border-gray-700 dark:text-gray-400 dark:hover:text-blue-500 cursor-pointer"
routerLink="/register"
>
<i class="pi pi-user-plus"></i>
Sign up
</a>
<a
class="flex items-center gap-x-2 font-medium text-gray-500 hover:text-blue-600 md:border-s md:border-gray-300 md:my-6 md:ps-6 dark:border-gray-700 dark:text-gray-400 dark:hover:text-blue-500 cursor-pointer"
routerLink="/login"
>
<i class="pi pi-user"></i>
Log in </a
>} @else if ( user ) {
<div class="card flex justify-content-center hs-dropdown">
<Button
class="flex items-center gap-x-2 font-medium text-gray-500 hover:text-blue-600 md:border-s md:border-gray-300 md:my-6 md:ps-6 dark:border-gray-700 dark:text-gray-400 dark:hover:text-blue-500 cursor-pointer"
>
<i class="pi pi-user"></i>
{{ user }}
</Button>
<div
class="hs-dropdown-menu hidden transition-[opacity,margin] duration hs-dropdown-open:opacity-100 opacity-0 min-w-[15rem] bg-white shadow-md rounded-lg p-2 mt-2 divide-y divide-gray-200 dark:bg-gray-800 dark:border dark:border-gray-700 dark:divide-gray-700"
aria-labelledby="hs-dropdown-with-dividers"
>
<div class="py-2 first:pt-0 last:pb-0">
<a
class="flex items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm text-gray-800 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-300 dark:focus:bg-gray-700"
href="#"
>
Upgrade License
</a>
</div>
<div class="py-2 first:pt-0 last:pb-0">
<a
class="flex items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm text-gray-800 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-300 dark:focus:bg-gray-700"
href="#"
>
Account Settings
</a>
<Button
class="flex items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm text-gray-100 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 dark:text-red-500 dark:hover:bg-gray-700 dark:hover:text-gray-300 dark:focus:bg-gray-700"
(click)="logout()"
>
<i class="pi pi-sign-out"></i>
Sign out
</Button>
</div>
</div>
</div>
}
{{ user}} 的值显示正常,但下拉列表未显示,因为它仍然坚持 this.user 的空值, 请记住,如果我重新加载页面,一切都会正常工作
我尝试将 BehaviourSubject 更改为 EventEmitter,但最终结果仍然相同,
我认为问题是因为标头在所有内容之前初始化,因为它始终存在于 app.component.html 中,这就是为什么它没有读取所需的值,但奇怪的是用户名的值显示
这是重新加载页面后的结果
您可以尝试像
user = this.userService.currentUser;
那样分配用户,然后在模板中使用异步管道!
@if (user$ | async; as user) {
// your code goes here
}