Ioni c 3, как отфильтровать массив, вложенный в 2 * ngFor? - PullRequest
3 голосов
/ 07 января 2020

Я хотел бы отфильтровать свойство day.children name на основе результатов поиска. Возникли трудности с вложенным * ngFor, потому что каждый полагается на второго. dayOverViewByGroup исходит от API. Я пытался обернуть day.children в функцию, подобную filterIt(day.children), но я получил бесконечный l oop. Спасибо.

У меня есть следующая (упрощенная) 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": [

    ]
  }
]

1 Ответ

3 голосов
/ 07 января 2020

Добавьте Observable filteredChildren$, который испускает отфильтрованные дочерние элементы к вашим day объектам.

Для создания filteredChildren$ вам нужна Observable из значений фильтра. Добавьте FormControl в панель поиска, чтобы вы могли прослушивать изменения его значения. (Вы должны импортировать ReactiveFormsModule)

Демо (Angular 8, Иони c 4, Rx JS 6)

Демо (Angular 5, Иони c 3, Rx JS 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))
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...