有一个 ChildComponent 显示可以填写的反应式表单。
填写表格并保存后,应通过向当前路线添加 id 来更改路线。在保存时,我们有一个完整的组件被渲染了2次,并且有一个闪烁的屏幕,但是如果您在将来向服务器添加请求,闪烁将会增加。如何摆脱这种影响,并且在保存的情况下不要渲染组件两次,并仅更改路由,或者也许有一种方法可以在切换路由时简单地不渲染相同的组件。
另外,当我们切换到 id 不正确的路由时,组件会渲染 2 次,并且应该重置表单,路由 id 就会消失。
根路由
import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
import {AppComponent} from "./app.component";
const routes: Routes = [
{
path: '',
component: AppComponent,
loadChildren: () => import('./root/parent.module').then(m => m.ParentModule)
},
{
path: 'child',
loadChildren: () => import('./child/child.module').then(m => m.ChildModule)
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {
}
子路由
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {RouterModule, Routes} from "@angular/router";
import {ChildComponent} from "./child.component";
const routes: Routes = [
{
path: '',
component: ChildComponent
},
{
path: ':id',
component: ChildComponent
}
]
@NgModule({
declarations: [],
imports: [
CommonModule,
RouterModule.forChild(routes)
],
exports: [RouterModule],
})
export class ChildRoutingModule {
}
状态
export interface Card {
id: string;
name: string;
description: string
}
export const STATE: Card[] = [
{
id: '1',
name: 'First',
description: 'First'
}, {
id: '2',
name: 'Second',
description: 'Second'
}
]
html 子组件
<a routerLink="/">to Root</a>
<div *ngFor="let item of STATE">
<a [routerLink]="'/child/' + item.id">to {{ item.name }}</a>
</div>
<form
(ngSubmit)="onSubmit()"
[formGroup]="formGroup"
style="display: flex; flex-direction: column; width: 200px"
>
<label>Name:
<input style="display: inline-block; width: 200px; padding: 0; margin: 0; box-sizing: border-box"
formControlName="name">
</label>
<label>Description:
<textarea style="display: inline-block; width: 200px; padding: 0; margin: 0; box-sizing: border-box; resize: none"
formControlName="description"></textarea>
</label>
<button style="width: 100%" type="submit" [disabled]="formGroup.invalid">Submit</button>
</form>
组件子组件
import {Component, OnDestroy, OnInit} from '@angular/core';
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
import {ActivatedRoute, Router} from "@angular/router";
import {STATE} from "../state";
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrl: './child.component.css'
})
export class ChildComponent implements OnInit, OnDestroy {
readonly STATE = STATE;
formGroup: FormGroup = this.formBuilder.group({
name: ['', Validators.required],
description: ['', Validators.required]
});
constructor(
private formBuilder: FormBuilder,
private activatedRoute: ActivatedRoute,
private router: Router) {
}
ngOnInit() {
console.log('ngOnInit')
const id = this.activatedRoute.snapshot.params['id']
if (id) {
const item = STATE.find(el => el.id === id)
if (item) this.formGroup.patchValue(item)
else this.router.navigate(['..'], {relativeTo: this.activatedRoute})
} else {
}
}
ngOnDestroy() {
console.log('ngOnDestroy')
}
onSubmit() {
const id = this.activatedRoute.snapshot.params['id']
if (id) {
const itemIndex = STATE.findIndex(el => el.id === id)
if (itemIndex) {
STATE[itemIndex].id = id.toString()
STATE[itemIndex].name = this.formGroup.value.name
STATE[itemIndex].description = this.formGroup.value.description
}
} else {
const random = Math.floor(Math.random() * 1000000)
STATE.push({
id: random.toString(),
name: this.formGroup.value.name,
description: this.formGroup.value.description
})
this.router.navigate(['./', random], {relativeTo: this.activatedRoute})
}
}
}
您遇到的问题与路由重用策略有关。要解决这个问题,您必须声明自己的路由重用规则:
import { RouteReuseStrategy } from '@angular/router';
export class CustomRouteReuseStrategy implements RouteReuseStrategy {
...
}
然后在您的 app.module 提供程序中提供它:
providers: [
...
{ provide: RouteReuseStrategy, useClass: CustomRouteReuseStrategy }
]