You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular路由复用组件:医师CRUD不同路由实现差异化输出

如何在Angular中复用组件实现CRUD的不同路由场景?

这场景太常见了,复用组件能大幅减少冗余代码,咱们一步步来拆解实现方式:

1. 注入路由服务,获取当前路由状态

首先在PhysicianComponent里注入ActivatedRoute和Router,这样就能拿到当前的路由信息,判断用户处于哪个操作场景:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';

@Component({
  selector: 'app-physician',
  templateUrl: './physician.component.html',
  styleUrls: ['./physician.component.css']
})
export class PhysicianComponent implements OnInit {
  // 定义操作模式:list/create/update
  currentMode: 'list' | 'create' | 'update' = 'list';
  // 存储单个医师数据(create/update时用)
  physicianData: any;
  // 存储医师列表数据(list时用)
  physicianList: any[] = [];

  constructor(
    private route: ActivatedRoute,
    private router: Router
  ) { }

  ngOnInit(): void {
    // 监听路由变化,实时更新模式和对应逻辑
    this.router.events.subscribe(() => {
      this.setCurrentMode();
      this.handleModeLogic();
    });

    // 初始化时先执行一次
    this.setCurrentMode();
    this.handleModeLogic();
  }
}

2. 编写路由模式判断与数据处理逻辑

在组件内添加两个核心方法:一个用来识别当前路由对应的操作模式,另一个根据模式处理对应的数据逻辑:

private setCurrentMode(): void {
  const urlSegments = this.router.url.split('/');
  const lastSegment = urlSegments[urlSegments.length - 1];
  
  if (lastSegment === 'create') {
    this.currentMode = 'create';
  } else if (lastSegment.startsWith('update')) {
    this.currentMode = 'update';
  } else {
    this.currentMode = 'list';
  }
}

private handleModeLogic(): void {
  switch (this.currentMode) {
    case 'list':
      // 调用服务加载医师列表,这里用模拟数据示例
      this.loadPhysicianList();
      break;
    case 'create':
      // 初始化空的医师对象,用于表单双向绑定
      this.physicianData = { name: '', title: '', department: '' };
      break;
    case 'update':
      // 从路由参数中获取医师ID,加载对应详情
      const physicianId = this.route.snapshot.paramMap.get('id');
      if (physicianId) {
        this.loadPhysicianDetail(physicianId);
      }
      break;
  }
}

// 模拟列表加载方法,实际替换为你的API调用
private loadPhysicianList(): void {
  // this.physicianService.getList().subscribe(data => {
  //   this.physicianList = data;
  // });
  this.physicianList = [
    { id: 1, name: '张医生', title: '主任医师', department: '内科' },
    { id: 2, name: '李医生', title: '副主任医师', department: '外科' }
  ];
}

// 模拟详情加载方法,实际替换为你的API调用
private loadPhysicianDetail(id: string): void {
  // this.physicianService.getDetail(id).subscribe(data => {
  //   this.physicianData = data;
  // });
  this.physicianData = { id: 3, name: '王医生', title: '主治医师', department: '儿科' };
}

3. 模板中根据模式渲染差异化UI

在physician.component.html里用*ngIf或*ngSwitch区分不同模式的界面,实现列表、表单的复用:

<!-- 列表模式 -->
<div *ngIf="currentMode === 'list'">
  <h2>医师列表</h2>
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>姓名</th>
        <th>职称</th>
        <th>科室</th>
        <th>操作</th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let physician of physicianList">
        <td>{{ physician.id }}</td>
        <td>{{ physician.name }}</td>
        <td>{{ physician.title }}</td>
        <td>{{ physician.department }}</td>
        <td>
          <button (click)="router.navigate(['/physician/view', physician.id])">查看</button>
          <button (click)="router.navigate(['/physician/update', physician.id])">编辑</button>
        </td>
      </tr>
    </tbody>
  </table>
  <button (click)="router.navigate(['/physician/create'])">新增医师</button>
</div>

<!-- 创建/编辑模式(复用表单) -->
<div *ngIf="currentMode === 'create' || currentMode === 'update'">
  <h2>{{ currentMode === 'create' ? '新增医师' : '编辑医师' }}</h2>
  <form (ngSubmit)="onSubmit()">
    <div>
      <label>姓名:</label>
      <input type="text" [(ngModel)]="physicianData.name" name="name" required>
    </div>
    <div>
      <label>职称:</label>
      <input type="text" [(ngModel)]="physicianData.title" name="title" required>
    </div>
    <div>
      <label>科室:</label>
      <input type="text" [(ngModel)]="physicianData.department" name="department" required>
    </div>
    <button type="submit">{{ currentMode === 'create' ? '提交' : '更新' }}</button>
    <button type="button" (click)="router.navigate(['/physician/list'])">返回列表</button>
  </form>
</div>

4. 处理路由参数变化的边界情况

如果用户在编辑页面直接切换ID(比如从update/3跳转到update/4),只靠路由快照会拿不到新参数,需要订阅paramMap监听参数变化:

ngOnInit(): void {
  // 监听路由参数变化(针对update模式)
  this.route.paramMap.subscribe(params => {
    if (this.currentMode === 'update') {
      const physicianId = params.get('id');
      if (physicianId) {
        this.loadPhysicianDetail(physicianId);
      }
    }
  });

  // 监听路由整体变化,处理模式切换
  this.router.events.subscribe(() => {
    this.setCurrentMode();
    this.handleModeLogic();
  });
}

这样就能完美复用一个组件实现三种不同的路由场景,逻辑清晰还能减少重复代码~

内容的提问来源于stack exchange,提问作者Abel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:37:54