Angular 4/5:按设备类型筛选下拉选项问题求助
解决方案:按设备类型筛选下拉选项
首先看你的代码,主要有几个问题导致筛选不生效:
- 不必要的重复API调用和错误的筛选逻辑
- 模板里没有根据当前设备类型ID过滤设备选项
- 存在语法和引用错误(比如
trackStatusById方法未定义)
下面是具体的修复步骤:
1. 重构Component.ts的数据获取逻辑
你现在在循环里调用equipmentService.find完全多余——因为已经通过equipmentService.query()拿到了所有设备数据。而且嵌套订阅会让代码难以维护,建议用RxJS的forkJoin并行获取两类数据,同时可以提前把设备按equipmentTypeId分组,方便后续模板高效使用:
import { forkJoin } from 'rxjs'; // ... 其他必要导入 export class YourComponent { equipment: Equipment[]; equipmentType: EquipmentType[]; // 新增:按设备类型ID分组的设备映射 equipmentByTypeId: { [key: number]: Equipment[] } = {}; // 存储每个类型对应的选中设备ID selectedEquipmentIds: { [key: number]: number | null } = {}; constructor( private equipmentService: EquipmentService, private equipmentTypeService: EquipmentTypeService ) {} ngOnInit() { // 并行获取设备类型和设备数据 forkJoin([ this.equipmentTypeService.query(), this.equipmentService.query() ]).subscribe( ([typeRes, equipRes]: [ResponseWrapper, ResponseWrapper]) => { this.equipmentType = typeRes.json; this.equipment = equipRes.json; // 按equipmentTypeId分组设备 this.equipmentByTypeId = this.equipment.reduce((acc, equip) => { const typeId = equip.equipmentTypeId; if (!acc[typeId]) { acc[typeId] = []; } acc[typeId].push(equip); return acc; }, {} as { [key: number]: Equipment[] }); }, (res: ResponseWrapper) => this.onError(res.json) ); } trackEquipmentById(index: number, item: Equipment) { return item.id; } trackEquipmentTypeById(index: number, item: EquipmentType) { return item.id; } // ... 你的onError错误处理方法 }
2. 修改Component.html实现筛选
现在可以用提前分组好的数据(性能更优),或者直接在模板内过滤,两种方式任选:
方式一:使用预分组数据(推荐,适合数据量较大的场景)
<div *ngFor="let equipmentOption of equipmentType; trackBy: trackEquipmentTypeById"> <span>{{equipmentOption.description}}</span> <select class="form-control" id="field_issuedBy_{{equipmentOption.id}}" name="issuedBy_{{equipmentOption.id}}" [(ngModel)]="selectedEquipmentIds[equipmentOption.id]" > <option [ngValue]="null"></option> <option [ngValue]="equipmentOpt.id" *ngFor="let equipmentOpt of equipmentByTypeId[equipmentOption.id] || []; trackBy: trackEquipmentById" > {{equipmentOpt.description}} </option> </select> </div>
注意:给每个select设置唯一的
id和name,避免表单元素冲突;equipmentByTypeId[equipmentOption.id] || []是为了处理没有对应设备的类型,避免报错。
方式二:模板内直接过滤(简洁,适合小数据量场景)
如果不想提前分组,可以自定义一个过滤管道:
import { Pipe, PipeTransform } from '@angular/core'; import { Equipment } from './equipment.model'; @Pipe({ name: 'filterByEquipmentTypeId' }) export class FilterByEquipmentTypeIdPipe implements PipeTransform { transform(equipments: Equipment[], typeId: number): Equipment[] { if (!equipments || !typeId) return []; return equipments.filter(equip => equip.equipmentTypeId === typeId); } }
别忘了在你的模块中声明这个管道。
然后修改模板:
<div *ngFor="let equipmentOption of equipmentType; trackBy: trackEquipmentTypeById"> <span>{{equipmentOption.description}}</span> <select class="form-control" id="field_issuedBy_{{equipmentOption.id}}" name="issuedBy_{{equipmentOption.id}}" [(ngModel)]="selectedEquipmentIds[equipmentOption.id]" > <option [ngValue]="null"></option> <option [ngValue]="equipmentOpt.id" *ngFor="let equipmentOpt of equipment | filterByEquipmentTypeId: equipmentOption.id; trackBy: trackEquipmentById" > {{equipmentOpt.description}} </option> </select> </div>
3. 修复原代码的其他小问题
- 原模板中的
trackStatusById改为trackEquipmentById,和component中定义的方法对应 - 原component里的
filterProtection筛选逻辑没有返回值,且条件错误(应该匹配equipmentTypeId而非设备ID)
这样修改后,每个设备类型对应的下拉框就只会显示属于该类型的设备选项了。
内容的提问来源于stack exchange,提问作者DESH
相关产品推荐
相关产品推荐

