Angular 无法在 ngOnInit 中获取本地存储值

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

我使用 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 中,这就是为什么它没有读取所需的值,但奇怪的是用户名的值显示

这是重新加载页面后的结果

angular rxjs local-storage
1个回答
0
投票

您可以尝试像

user = this.userService.currentUser;
那样分配用户,然后在模板中使用异步管道!

@if (user$ | async; as user) {
// your code goes here
}
© www.soinside.com 2019 - 2024. All rights reserved.