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

Angular中嵌套对象字段registration.patientId搜索失效问题

问题说明

我希望将{{item.registration.patientId}}设置为可搜索字段,替换当前的{{item.mainId}}。从返回的JSON数据可知,patientId是嵌套在registration对象中的字段。目前搜索{{item.mainId}}或顶层的sequence字段均可正常工作,但将TS文件中getDetail函数的mainId替换为patientId或registration.patientId后,搜索功能失效,始终显示全部10条数据。

相关代码文件

patient.component.html

<div>
    <input type="text" class="form-control" placeholder="ID" #myInput>
    <button (click)="getDetail(myInput.value)" type="button">Search</button>
</div>

<div *ngFor="let item of bills; let count = index">
    <div>{{count +1}}</div>
    <div>{{item.registration?.patientId}}</div>
    <div>{{item.mainId}}</div>
    <div>{{item.registration?.firstName}}</div>
    <div>{{item.registration?.mobile}}</div>
</div>

patient.component.ts

export class ViewBillsComponent implements OnInit {
  public bills = [] as Billing[];
  public componentQuery = new HttpParams();
  public paginationData = {} as Pagination;
  constructor(
    private coreService: CoreService,
  ) { }

  ngOnInit(): void {
    this.getBills();
  }

  getBills(){
    this.coreService.getBillings(this.componentQuery).subscribe({
      next: (res: any) => {
        this.bills = res.data;
        this.paginationData = res
      },
      error: (err) => {
        console.log(err);
      }
    })
  }

  getDetail(searchId= ''){
    console.log(searchId)
    this.componentQuery = this.componentQuery.set('mainId', searchId);
    console.log(this.componentQuery)
    this.getBills();
  }

  paginateTo(page:number){
    this.componentQuery = this.componentQuery.set('page', page)
    this.getBills()
  }
}

后端返回的JSON数据

{
    "status": "success",
    "data": [
        {
            "_id": "66ad004d952855f99c907d7c",
            "registration": {
                "_id": "66ad001f952855f99c907d1e",
                "firstName": "Test5001",
                "lastName": "Leone",
                "mobile": 3987298279,
                "createdAt": "2024-08-02T15:49:51.848Z",
                "updatedAt": "2024-08-02T15:49:51.848Z",
                "sequence": 21,
                "patientId": "PT21",
                "__v": 0
            },
            "amount": 0,
            "date": "2024-08-02T15:50:00.000Z",
            "createdAt": "2024-08-02T15:50:37.934Z",
            "updatedAt": "2024-08-02T15:50:37.934Z",
            "sequence": 45,
            "mainId": "ID45",
            "__v": 0
        },
        {
            "_id": "66ad003c952855f99c907d50",
            "registration": {
                "_id": "66ad003c952855f99c907d46",
                "firstName": "John",
                "lastName": "Wick",
                "mobile": 847900919,
                "createdAt": "2024-08-02T15:50:20.043Z",
                "updatedAt": "2024-08-02T15:50:20.043Z",
                "sequence": 22,
                "patientId": "PT22",
                "__v": 0
            },
            "amount": 500,
            "date": "2024-08-02T15:49:00.000Z",
            "createdAt": "2024-08-02T15:50:20.121Z",
            "updatedAt": "2024-08-02T15:50:20.121Z",
            "sequence": 44,
            "mainId": "ID44",
            "__v": 0
        }
    ]
}

core.services.ts

getBillings(params?: HttpParams) {
    return this.httpClient.get(
      `${environment.backend_base_url}billing`,
      {params}
    );
  }

interfaces文件

export interface patient {
    _id: string;
    registration?:any;
    sequence?: number;
    mainId?:string;
    date?:any;
    createdAt: Date;
    updatedAt: Date;
    is_active?:boolean;
}
解决方案

方案一:后端支持嵌套字段查询(推荐)

当前通过HttpParams将搜索参数传给后端,要实现嵌套字段registration.patientId的搜索,需做以下修改:

  1. 调整getDetail函数,将参数key改为registration.patientId,同时删除之前的mainId参数(避免参数冲突)
  2. 确保后端接口支持接收registration.patientId作为查询条件(比如MongoDB原生支持{"registration.patientId": 搜索值}的查询语法)

修改后的getDetail函数:

getDetail(searchId= ''){
    console.log(searchId)
    // 先清除旧的mainId参数,再设置新的嵌套字段查询参数
    this.componentQuery = this.componentQuery.delete('mainId').set('registration.patientId', searchId);
    console.log(this.componentQuery)
    this.getBills();
}

方案二:前端本地过滤(后端不支持时使用)

如果后端无法处理嵌套字段查询,可以先获取全量数据,再在前端完成过滤:

  1. 添加filteredBills数组用于存储过滤后的结果,保留原始bills作为数据源
  2. 修改getDetail函数,根据输入的ID匹配registration.patientId字段
  3. 更新HTML模板,循环展示过滤后的数组

修改后的patient.component.ts:

export class ViewBillsComponent implements OnInit {
  public bills = [] as Billing[];
  public filteredBills = [] as Billing[];
  public componentQuery = new HttpParams();
  public paginationData = {} as Pagination;
  constructor(
    private coreService: CoreService,
  ) { }

  ngOnInit(): void {
    this.getBills();
  }

  getBills(){
    this.coreService.getBillings(this.componentQuery).subscribe({
      next: (res: any) => {
        this.bills = res.data;
        this.filteredBills = [...this.bills]; // 初始化过滤数组
        this.paginationData = res
      },
      error: (err) => {
        console.log(err);
      }
    })
  }

  getDetail(searchId= ''){
    console.log(searchId)
    if(!searchId){
      this.filteredBills = [...this.bills]; // 输入为空时显示全部数据
      return;
    }
    // 模糊匹配patientId,忽略大小写
    this.filteredBills = this.bills.filter(item => 
      item.registration?.patientId?.toLowerCase().includes(searchId.toLowerCase())
    );
  }

  paginateTo(page:number){
    this.componentQuery = this.componentQuery.set('page', page)
    this.getBills()
  }
}

同时更新patient.component.html的循环对象:

<div *ngFor="let item of filteredBills; let count = index">
    <div>{{count +1}}</div>
    <div>{{item.registration?.patientId}}</div>
    <div>{{item.mainId}}</div>
    <div>{{item.registration?.firstName}}</div>
    <div>{{item.registration?.mobile}}</div>
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 03:04:54