如何在一个组件上制作多条路线,并且不要不必要地重绘它们,Angular

问题描述 投票:0回答:1

有一个 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})
    }
  }
}
javascript angular angular-routing angular-router angular-routerlink
1个回答
0
投票

您遇到的问题与路由重用策略有关。要解决这个问题,您必须声明自己的路由重用规则:

import { RouteReuseStrategy } from '@angular/router';
export class CustomRouteReuseStrategy implements RouteReuseStrategy {
...
}

然后在您的 app.module 提供程序中提供它:

providers: [
    ...
    { provide: RouteReuseStrategy, useClass: CustomRouteReuseStrategy }
]
© www.soinside.com 2019 - 2024. All rights reserved.