Angular router.navigate 后组件未更新

Angular Components is not updated after router.navigate

我有两个组成部分。 users.components.ts 和 register.components.ts。 users.components.ts 显示 table 用户,register.components.ts 是我们 add/edit 用户。

当我们 add/edit 用户通过 router.navigate() 重定向回 users.components.ts。但是,在刷新页面之前,用户 table 中看不到更改。

这似乎是一个常见问题,但我仍然找不到解决方案。这是我的代码

app-routing.module.ts

import { Routes, RouterModule } from '@angular/router';

import { AuthGuard } from './guards/auth.guard';
import { AdminGuard } from './guards/admin.guard';

import { RegisterComponent } from './components/register/register.component';
import { UsersComponent } from './components/users/users.component';

const routes: Routes = [
  { path: 'users', component: UsersComponent, canActivate: [AdminGuard] },
  { path: 'register', component: RegisterComponent, canActivate: [AdminGuard] },
  { path: 'login', component: LoginComponent },

  // otherwise redirect to users
  { path: '**', redirectTo: 'users' }
];

export const AppRouting = RouterModule.forRoot(routes);

users.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
import { first } from 'rxjs/operators'; // What is this? Look it up

import { MatPaginator, MatTableDataSource,
    MatDialog, MatDialogConfig
  } from '@angular/material';

import { User } from './../../models/user';
import { UserService } from './../../services/user.service';
import { AlertService } from './../../services/alert.service';

@Component({
  selector: 'app-users',
  templateUrl: './users.component.html',
  styleUrls: ['./users.component.scss']
})
export class UsersComponent implements OnInit {

  loading = false;

  displayedColumns: string[] = [
    'id',
    'name',
    'email',
    'contactNumber',
    'lastActive',
    'edit'
  ];

  users: User[] = [];
  dataSource = new MatTableDataSource<User>();

  @ViewChild(MatPaginator) paginator: MatPaginator;

  constructor(
    private router: Router,
    private route: ActivatedRoute,
    private userService: UserService,
    private alertService: AlertService
  ) {
    this.loadUsers();
    this.dataSource.paginator = this.paginator;
   }

  editUser(user: User): void {
    this.clear();
    window.localStorage.setItem('editUserId', user.id.toString());
    this.router.navigate(['register']);
  }

  addUser(): void {
    this.clear();
    this.router.navigate(['register']);
  }

  private async loadUsers() {
    this.loading = true;
    try {
      this.users = await this.userService.get().toPromise();
      this.dataSource = new MatTableDataSource<User>(this.users);
    } catch (error) {
      this.alertService.error(error);
    }
    this.loading = false;
  }

  private clear() {
    window.localStorage.removeItem('editUserId');
  }

}

register.component.ts

import { Component, OnInit } from '@angular/core';
import { first } from 'rxjs/operators';
import { Router } from '@angular/router';
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';

import { User } from './../../models/user';
import { CheckUsernameEmailRequest } from 'src/app/models/check.username.email.request';

import { UserService } from './../../services/user.service';
import { AlertService } from './../../services/alert.service';
import { ValidationService } from './../../services/validation.service';

@Component({
  selector: 'app-register',
  templateUrl: './register.component.html',
  styleUrls: ['./register.component.scss']
})
export class RegisterComponent implements OnInit {

  editUserId: string;
  userForm: FormGroup;
  loading = false;
  submitted = false;

  constructor(
    private formBuilder: FormBuilder,
    private router: Router,
    private userService: UserService,
    private alertService: AlertService,
    private validationService: ValidationService
  ) { }

  ngOnInit() {

    this.editUserId = window.localStorage.getItem('editUserId');

    const checkUsernameEmailRequest: CheckUsernameEmailRequest = <CheckUsernameEmailRequest>({
      userId: this.editUserId,
      usernameOrEmail: ''
    });

    this.userForm = this.formBuilder.group({
      firstName: ['', Validators.required],
      lastName: ['', Validators.required],
      contactNumber: this.validationService.phoneNumberValidators(),
      email: this.validationService.emailValidators(checkUsernameEmailRequest),
      username: this.validationService.usernameValidators(checkUsernameEmailRequest),
      password: ['', Validators.required],
      admin: false
    });

    if (this.editUserId) {
      this.loadUser();
    }
  }

  // convenience getter for easy access to form fields
  get controls() { return this.userForm.controls; }

  getErrorMessage(formControl: FormControl) {
    return this.validationService.getErrorMessage(formControl);
  }

  public onSubmit() {

    this.submitted = true;

    if (this.userForm.invalid) { return; }

    this.loading = true;

    const user: User = <User>({
      firstName: this.controls.firstName.value,
      lastName: this.controls.lastName.value,
      contactNumber: this.controls.contactNumber.value,
      email: this.controls.email.value,
      username: this.controls.username.value,
      password: this.controls.password.value,
      admin: this.controls.admin.value
    });

    if (this.editUserId) {
      this.edit(user);
    } else {
      this.register(user);
    }

    this.router.navigate(['users']);
  }

  private populateForm(user: any) {
    this.controls.firstName.setValue(user.firstName);
    this.controls.lastName.setValue(user.lastName);
    this.controls.contactNumber.setValue(user.contactNumber);
    this.controls.email.setValue(user.email);
    this.controls.username.setValue(user.username);
    this.controls.password.setValue(user.password);
    this.controls.admin.setValue(user.admin);
  }

  private loadUser() {
    this.userService
      .getById(+this.editUserId) // + operator is a quick way to convert a string to int
      .pipe(first())
        .subscribe(data => {
          this.populateForm(data);
        }, error => {
            this.alertService.error(error);
            this.loading = false;
        });
  }

  private register(user: User) {
    this.userService
      .register(user)
      .pipe(first())
        .subscribe(data => {
          this.alertService.handleResponse(data);
        }, error => {
          this.alertService.error(error);
          this.loading = false;
        });
  }

  private edit(user: User) {

    user.id = +this.editUserId;
    this.userService
        .update(user)
        .pipe(first())
        .subscribe(data => {
          this.alertService.handleResponse(data);
        }, error => {
            this.alertService.error(error);
            this.loading = false;
        });

    window.localStorage.removeItem('editUserId');
  }

}

user.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { User } from './../models/user';
import { ApiResponse } from './../models/api.response';
import { environment } from 'src/environments/environment';


@Injectable({ providedIn: 'root' })
export class UserService {

  apiUrl: string = environment.apiUrl;

  constructor(private http: HttpClient) { }

  get() {
    return this.http.get<User[]>(`${this.apiUrl}/users`);
  }

  getById(id: number) {
    return this.http.get(`${this.apiUrl}/users/${id}`);
  }

  register(user: User) {
    return this.http.post<ApiResponse>(`${this.apiUrl}/users/register`, user);
  }

  update(user: User) {
    return this.http.put<ApiResponse>(`${this.apiUrl}/users/edit`, user);
  }

}

您正在同步重定向,在调用 edit/register 方法后,尝试在这些方法的订阅回调中重定向

该行为的原因可能是在您的 UsersComponent 中,您在构造函数中而不是在 ngOnInit() 中调用方法 loadUsers()。

尝试将此方法移至 ngOnInit()。