简体   繁体   中英

Angular Components is not updated after router.navigate

I have two components. users.components.ts and register.components.ts. users.components.ts displays a table of users and register.components.ts is where we add/edit users.

When we add/edit the user the users is redirected back to the users.components.ts via router.navigate(). However, the changes are not seen in the users table until the page is refreshed.

This seems to be a common problem, but i still can't find a solution. Here is my code

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方法之后,请尝试在这些方法的订阅回调中进行重定向

the reason for that behavior might be that in your UsersComponent you call method loadUsers() in the constructor instead of in ngOnInit().

Try moving this method to ngOnInit().

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM