如何在Angular中添加新记录时自动将新记录显示到列表中?

How to automatically display the new record to a list when a new record is added in Angular?

我目前正在开发一个 Angular 应用程序,使用 CRUD 操作和 Springboot API 作为后端。问题是当我添加一个新用户时,它已成功添加但不会自动显示在列表中。它需要重新加载页面以显示更新后的列表。

这是我的添加-user.component.ts:

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { User } from '../user';

import { UserService } from '../user.service';

@Component({
  selector: 'app-add-user',
  templateUrl: './add-user.component.html',
  styleUrls: ['./add-user.component.css']
})
export class AddUserComponent implements OnInit {

  user: User = new User();
  submitted = false;

  constructor(
    private userService: UserService,
    private router: Router,
  ) { }

  ngOnInit(): void {
  }

  save() {
    this.userService
    .addUser(this.user).subscribe(data => {
      console.log(data)
      this.user = new User();
      this.goToList();
    },
      error => console.log(error));
  }

  onSubmit() {
    this.submitted = true;
    this.save();
    this.userService.getUserList();
  }

  goToList() {
    this.router.navigate(['']);
  }
}

这是我的用户-list.component.ts:

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { BehaviorSubject, Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { User } from '../user';
import { UserDetailsComponent } from '../user-details/user-details.component';
import { UserService } from '../user.service';

@Component({
  selector: 'app-user-list',
  templateUrl: './user-list.component.html',
  styleUrls: ['./user-list.component.css']
})
export class UserListComponent implements OnInit {
  users: Observable<User[]>;
  toUserDetails: UserDetailsComponent;
  refreshUsers = new BehaviorSubject<boolean>(true);

  constructor(
    private userService: UserService,
    private router: Router
  ) { }

  ngOnInit(): void {
    this.reloadData();
  }

  reloadData() {
    this.users = this.refreshUsers.pipe(switchMap(_ => this.userService.getUserList()));
    this.refreshUsers.next(true);
  }


  deleteUser(id: number) {
    this.userService.deleteUser(id)
      .subscribe(data => {
        console.log(data);
        this.reloadData();
      }, error => console.log(error));
  }

  userDetails(id: number) {
    this.router.navigate(['details', id]);
  }

  updateUser(id: number) {
    this.router.navigate(['update', id]);
  }
}

这是我的 user.service.ts

import { HttpClient } from '@angular/common/http'
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { environment } from 'src/environments/environment';
import { User } from './user';

@Injectable({
  providedIn: 'root'
})
export class UserService {
  user: User[];
  users: BehaviorSubject<User[]> = new BehaviorSubject([]);

  private BASE_URL = environment.apiBaseUrl;

  constructor(
    private http: HttpClient
  ) { }

  public getUser(id:number): Observable<User> {
    return this.http.get<User>(`${this.BASE_URL}/users/${id}`);
  }

  public addUser(user: User): Observable<User> {
    return this.http.post<User>(`${this.BASE_URL}/add`, user);
  }

  public updateUser(id: number, value: any): Observable<User> {
    return this.http.put<User>(`${this.BASE_URL}/update/${id}`, value);
  }

  public deleteUser(id: number): Observable<any> {
    return this.http.delete(`${this.BASE_URL}/delete/${id}`, {responseType: 'text'});
  }

  public getUserList(): Observable<User[]> {
    return this.http.get<User[]>(`${this.BASE_URL}/users`);
  }

}

谁能帮我解决这个问题?谢谢。

为什么不在您的 user.service.ts class 定义中使用 users 属性。您可以使用 users BehaviorSubject 而不是订阅 API 调用,只需在每次调用结束时更新它并订阅它。

所以你会有这样的东西:

user-list.component.ts

//...
reloadData() {
  this.users = this.refreshUsers
    // so instead of rerunning the get user list function you can just get the list
    .pipe(switchMap( _=> this.userService.users));
  this.refreshUsers.next(true);
}
//...

现在您只需确保 user.service.ts 更新列表 每个 API 响应。

user.service.ts

//...
export class UserService {
  user: User[];
  users: BehaviorSubject<User[]> = new BehaviorSubject([]);

  private BASE_URL = environment.apiBaseUrl;

  constructor(
    private http: HttpClient
  ) { }

  public getUser(id:number): Observable<User> {
    return this.http.get<User>(`${this.BASE_URL}/users/${id}`)
      .pipe(map((user) => {
        this.user.push(user);
        this.users.next(this.user);

        return user;
      }));
  }

  public addUser(user: User): Observable<User> {
    return this.http.post<User>(`${this.BASE_URL}/add`, user)
      .pipe(map((user) => {
        this.user.push(user);
        this.users.next(this.user);

        return user;
      }));
  }


  // With this function you would find the user and update them but this might
  // be inefficient, so what I would suggest is to use a Record<string, User> type
  // instead of User[] to keep your users then it makes the work easier.
  public updateUser(id: number, value: any): Observable<User> {
    return this.http.put<User>(`${this.BASE_URL}/update/${id}`, value);
  }

  // The case of deleteUser is the same here as well
  public deleteUser(id: number): Observable<any> {
    return this.http.delete(`${this.BASE_URL}/delete/${id}`, {responseType: 'text'});
  }

  public getUserList(): Observable<User[]> {
    return this.http.get<User[]>(`${this.BASE_URL}/users`)
      .pipe(map((users) => {
        this.user = users;
        this.users.next(this.user);

        return users;
      }));
  }

}

有了这个,你就不会提出太多不必要的要求,因为你有 为您的用户创建了一个小型数据缓存。

对于这种情况,我通常使用 ngrx。我肯定会 说检查一下,它将提供更好的解决方案 这个。