angular - Angular 组件在 router.navigate 之后没有更新
问题描述
我有两个组件。users.components.ts 和 register.components.ts。users.components.ts 显示一个用户表,而 register.components.ts 是我们添加/编辑用户的地方。
当我们添加/编辑用户时,用户通过 router.navigate() 重定向回 users.components.ts。但是,在刷新页面之前,不会在 users 表中看到更改。
这似乎是一个常见问题,但我仍然找不到解决方案。这是我的代码
应用程序路由.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');
}
}
注册组件.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');
}
}
用户服务.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);
}
}
解决方案
您正在同步重定向,在调用编辑/注册方法后,尝试在这些方法的订阅回调中重定向
推荐阅读
- sql - 检查约束以防止 2 行或更多行的数值为 1
- reactjs - Ref 调整大小时返回 null
- python - 无法使用 self 调用函数
- javascript - 如何从anckor标签的html链接中提取新闻文章
- javascript - 使用 Howler.js 流式传输原始音频文件
- php - Codeigniter 如何从包含多个文件的子文件夹加载视图文件
- php - 选择每个作者的引用并从关系表中选择标签
- java - 如何使用 xpath 或 CSS 选择器识别虚拟表中的第一条记录
- postgresql - 在插入 Postgresql 时过滤 bigint 值
- php - 提交表单后在 Codeigniter 中重新加载当前 URL