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

如何实现带搜索功能的Angular下拉选择框

为Angular Material mat-select实现动态数据搜索功能

实现思路

在mat-form-field内添加搜索输入框,结合组件内的过滤逻辑对SupplierDTO[]动态数据做实时过滤,实现带搜索的下拉选择功能。


修改后的HTML代码

<mat-form-field class="box" appearance="fill">
  <mat-label>Supplier</mat-label>
  <!-- 新增搜索输入框,绑定关键词并触发过滤 -->
  <input matInput placeholder="搜索供应商" [(ngModel)]="searchKeyword" (input)="filterSuppliers()">
  
  <mat-select formControlName="supplierId" (selectionChange)="selectedSupplier($event)">
    <!-- 遍历过滤后的供应商数组 -->
    <mat-option *ngFor="let item of filteredSuppliers" [value]="item.id">
      {{item.companyName}}
    </mat-option>
  </mat-select>
</mat-form-field>

修改后的TS代码

import { Component, OnInit } from '@angular/core';
import { MatSelectChange } from '@angular/material/select';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { SupplierDTO } from './your-supplier-dto-path'; // 替换为实际文件路径
import { YourSupplierService } from './your-supplier-service-path'; // 替换为实际服务路径

export class DeliveryReceiptComponent implements OnInit {
  supplier: SupplierDTO[] = [];
  filteredSuppliers: SupplierDTO[] = [];
  searchKeyword: string = '';
  deliveryReceiptForm: FormGroup;
  selectedSupplierID: number | undefined;
  APRDisplayed: boolean = false;
  dbmRequired: string = 'your-dbm-target-value'; // 替换为实际判断值

  constructor(
    private supplierSvc: YourSupplierService,
    private fb: FormBuilder
  ) {
    // 初始化表单结构
    this.deliveryReceiptForm = this.fb.group({
      supplierId: [''],
      Bank: [''],
      AccountName: [''],
      AccountNumber: [''],
      Branch: [''],
      purchaseRequestNumber: [''],
      purchaseRequestDate: [''],
      drNumFrSupplier: [''],
      drDate: [''],
      aprNum: [''],
      aprDate: [''],
      purchaseOrderNumber: [''],
      purchaseOrderDate: [''],
      saleInvoiceDate: [''],
      saleInvoiceNumber: ['']
    });
  }

  ngOnInit(): void {
    // 从服务拉取动态供应商数据
    this.supplierSvc.getSuppliers().subscribe((data: SupplierDTO[]) => {
      this.supplier = data;
      this.filteredSuppliers = [...this.supplier]; // 初始化过滤数组
    });
  }

  // 供应商过滤逻辑
  filterSuppliers(): void {
    if (!this.searchKeyword.trim()) {
      this.filteredSuppliers = [...this.supplier];
      return;
    }
    const keyword = this.searchKeyword.toLowerCase();
    this.filteredSuppliers = this.supplier.filter(item => 
      item.companyName.toLowerCase().includes(keyword)
      // 可扩展搜索字段,比如:item.id.toString().includes(keyword)
    );
  }

  selectedSupplier(trigger: MatSelectChange) {
    this.selectedSupplierID = trigger.value;
    this.supplierSvc.getSupplierDR(this.selectedSupplierID).subscribe((response: any) => {
      const splitted = response.split(":", 4);
      this.deliveryReceiptForm.get('Bank')?.patchValue(splitted[0]);
      this.deliveryReceiptForm.get('AccountName')?.patchValue(splitted[1]);
      this.deliveryReceiptForm.get('AccountNumber')?.patchValue(splitted[2]);
      this.deliveryReceiptForm.get('Branch')?.patchValue(splitted[3]);

      if (this.deliveryReceiptForm.get('AccountName')?.value === this.dbmRequired) {
        this.APRDisplayed = true;
        this.setFieldValidators([
          'purchaseRequestNumber', 'purchaseRequestDate', 'drNumFrSupplier', 
          'drDate', 'aprNum', 'aprDate'
        ], true);
        this.deliveryReceiptForm.get('purchaseOrderDate')?.setValue('0001-01-01');
        this.deliveryReceiptForm.get('saleInvoiceDate')?.setValue('0001-01-01');
        this.deliveryReceiptForm.get('aprDate')?.reset();
      } else {
        this.APRDisplayed = false;
        this.setFieldValidators([
          'purchaseOrderNumber', 'purchaseOrderDate', 'purchaseRequestNumber', 
          'purchaseRequestDate', 'saleInvoiceDate', 'saleInvoiceNumber', 
          'drNumFrSupplier', 'drDate'
        ], true);
        this.deliveryReceiptForm.get('aprDate')?.setValue('0001-01-01');
      }
    });
  }

  // 复用的表单验证器设置方法
  private setFieldValidators(controlNames: string[], required: boolean): void {
    controlNames.forEach(name => {
      const control = this.deliveryReceiptForm.get(name);
      if (control) {
        required ? control.addValidators(Validators.required) : control.clearValidators();
        control.updateValueAndValidity();
      }
    });
  }
}

关键说明

  • 搜索交互:通过双向绑定searchKeyword和输入事件触发过滤,实现实时搜索
  • 过滤逻辑:统一转为小写避免大小写敏感,支持扩展多个搜索字段(如供应商ID)
  • 数据初始化:从服务获取动态数据后同步初始化过滤数组,保证初始状态显示全量数据
  • 代码优化:提取验证器设置为复用方法,简化分支逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 12:45:29