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
相关产品推荐
相关产品推荐

