There is a ChildComponent that displays a reactive form that can be filled.
After filling the form and saving it, the route should be changed by adding an id to the current route. At the moment when saving we have a complete component is rendered 2 times and there is a blinking screen, but if you add in future request to the server, the blinking will increase. How to get rid of this effect and in case of saving do not render the component 2 times, and change only route or maybe there is a way to simply not render the same component when switching routes.
Also, when we switch to a route with an incorrect id, the component is rendered 2 times, and should just reset the form and the route id disappears.
Root Routing
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 {
}
Child Routing
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 {
}
State
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 ChildComponent
<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>
component ChildComponent
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})
}
}
}
The issue you have relates to routes reuse strategy. To solve it you have to declare your own rules for routes reusing:
then provide it in your app.module providers: