Ionic 3 如何过滤嵌套在 2 *ngFor 中的数组?

Ionic 3 how to filter array nested in 2 *ngFor?

我想根据搜索输入过滤 day.children name 属性。嵌套 *ngFor 有困难,因为一个依赖于第二个。 dayOverViewByGroup 来自 API。 我试图将 day.children 包装在 filterIt(day.children) 之类的函数中,但我得到了无限循环。谢谢。

我有以下(简化)html结构

<ion-searchbar placeholder="Suchen..." (ionInput)="searchChildren($event)" padding></ion-searchbar>
<ion-grid *ngFor="let day of dayOverViewByGroup; let i = index" padding>
  <ion-card *ngFor="let child of day.children; let j = index">
  <h1>{{child.name}}</h1>
</ion-grid>

dayOverview 变量示例数据来自 API

// dayOverview variable example data from API

[
  {
    "name": "Kindergarden 1",
    "presence_id": 25,
    "totalChildren": 3,
    "totalCheckinChildren": 1,
    "children": [
      {
        "name": "John Doe",
        "daycareComment": null,
        "parentComment": null,
        "id": "10633",
        "away": null,
        "checkin": [],
        "additionalDay": false,
        "remarks": "",
        "awayClass": "",
        "reason": "",
        "addtionalClass": "",
        "disableToggle": false,
        "disabled": false,
        "checkout": "Nicht anwesend",
        "class": "notcheckin"
      },
      {
        "name": "Jane Doe",
        "daycareComment": null,
        "parentComment": null,
        "id": "8322",
        "away": null,
        "checkin": [],
        "additionalDay": false,
        "remarks": "",
        "awayClass": "",
        "reason": "",
        "addtionalClass": "",
        "disableToggle": false,
        "disabled": false,
        "checkout": "Nicht anwesend",
        "class": "notcheckin"
      },
      {
        "name": "Bastian Paper",
        "daycareComment": null,
        "parentComment": null,
        "id": "86999",
        "away": null,
        "checkin": [],
        "additionalDay": false,
        "remarks": "",
        "awayClass": "",
        "reason": "",
        "addtionalClass": "",
        "disableToggle": false,
        "disabled": true,
        "class": "checkin",
        "checkout": "Anwesend"
      }
    ]
  },
  {
    "name": "Kindergarden 2",
    "presence_id": 26,
    "totalChildren": 1,
    "totalCheckinChildren": 0,
    "children": [
      {
        "name": "Thomas Mueller",
        "daycareComment": null,
        "parentComment": null,
        "id": "86900",
        "away": null,
        "checkin": [],
        "additionalDay": false,
        "remarks": "",
        "awayClass": "",
        "reason": "",
        "addtionalClass": "",
        "disableToggle": false,
        "disabled": false,
        "checkout": "Nicht anwesend",
        "class": "notcheckin"
      }
    ]
  },
  {
    "name": "Kindergarden 3",
    "presence_id": 27,
    "totalChildren": 1,
    "totalCheckinChildren": 0,
    "children": [

    ]
  }
]

添加一个 Observable filteredChildren$ 将过滤后的子项发送到您的 day 对象。

要创建 filteredChildren$,您需要一个过滤值的 Observable。将 FormControl 添加到您的搜索栏,以便您可以收听其值的变化。 (您必须导入 ReactiveFormsModule

Demo (Angular 8, Ionic 4, RxJS 6)

Demo (Angular 5, Ionic 3, RxJS 5.5)

<ion-searchbar placeholder="Suchen..." [formControl]="filterControl" padding></ion-searchbar>
<ion-grid *ngFor="let day of dayOverViewByGroup$ | async; let i = index" padding>       
  <ion-card *ngFor="let child of day.filteredChildren$ | async; let j = index">
    <h1>{{child.name}}</h1>
  </ion-card>
</ion-grid>
export class Component {
  filterControl = new FormControl();
  dayOverViewByGroup$: Observable<any>

  ngOnInit() {
    const filter$: Observable<string> = this.filterControl.valueChanges.pipe(
      startWith(''),
      debounceTime(100), 
      distinctUntilChanged(),
      share() // we use filter$ multiple times so we share a single subscription to the source
    );
    this.dayOverViewByGroup$ = this.fetchData().pipe(
      map(days => days.map(day => (
        {
          ...day,
          // add an Observable that emits an array of filtered children
          filteredChildren$: filter$.pipe(this.filterFrom(day.children))
        }
      )))
    );
  }

  fetchData(): Observable<any[]> {
    // fetch data from Api
    return of(data);
  }

  filterFrom(children: { name: string }[]) {
    return (filter$: Observable<string>) => filter$.pipe(
      // the filter logic (add your own here)
      map(f => children.filter(child => child.name.toLowerCase().indexOf(f.toLowerCase()) > -1))
    );
  }
}