如何将 ionic 4 搜索栏与 *ngFor 一起使用

How to use ionic 4 search bar with *ngFor

我构建了一个页面,该页面使用搜索栏通过 *ngFor 数组进行过滤。当我在搜索栏中输入时它表现正常,但是当我删除或返回 space 文本时它不会更新。如果我从数据服务的静态列表中提取一个数组但不使用我从 ApolloQueryResult 中提取的数据,它会正常工作。任何帮助将不胜感激。

html

<ion-content padding>
  <div *ngIf="loading">Loading...</div>
  <div *ngIf="error">Error loading data</div>

  <ion-toolbar>
    <ion-searchbar [(ngModel)]="searchTerm" (ionChange)="setFilteredItems()" showCancelButton="focus"></ion-searchbar>
  </ion-toolbar>

  <ion-card *ngFor="let data of info">
    <ion-card-content>
      {{data.TypeOfNotification}}
    </ion-card-content>
  </ion-card>
</ion-content>

ts

import { Component, OnInit } from '@angular/core';
import { Apollo } from 'apollo-angular';
import { ApolloQueryResult } from 'apollo-client';
import { QueryTodoService } from '../../services/query-todo.service';
import { Storage } from '@ionic/storage';

@Component({
  selector: 'app-tab-to-do',
  templateUrl: './tab-to-do.page.html',
  styleUrls: ['./tab-to-do.page.scss'],
})

export class TabToDoPage implements OnInit {
  info: any;
  error: any;
  loading: boolean;
  searchTerm: string;

  constructor( 
    private apollo: Apollo,
    private queryTodoService: QueryTodoService,
    private storage: Storage
  ) { }

  setFilteredItems() {
    this.info = this.filterItems(this.searchTerm);
  }

  filterItems(searchTerm){
    return this.info.filter((item) => {
      return item.TypeOfNotification.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1;
    });
  }

  // or

  setFilteredItemsAlt(event) {
    const searchTerm = event.srcElement.value;

    if (!searchTerm) {
      return;
    }

    this.info = this.info.filter(item => {
      if (item.TypeOfNotification && searchTerm) {
        if (item.TypeOfNotification.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1) {
          return true;
        }
        return false;
      }
    });
  }

  ngOnInit() {
    this.storage.get('AccessToken').then((_token) => {
      this.apollo.watchQuery({
        query:this.queryTodoService.ToDoQuery,
        fetchPolicy: 'cache-first',
      })
      .valueChanges.subscribe((result: ApolloQueryResult<any> ) => {
        this.loading = result.loading;
        this.info = result.data.notifications.Notifications;
        console.log('first info', this.info );
        this.error = result.errors;
      });
    });
  }
}

这是因为你每次开火都会覆盖this.info setFilteredItems():

setFilteredItems() {
    //Overwrite this.info with new filtered data set.
    this.info = this.filterItems(this.searchTerm);
}

旧值已被过滤掉,不再存在 - 这就是 *ngFor="let data of info" 不显示它们的原因。

您可以做的是在您的 ts 文件中设置一个等于 this.info 的新变量 - 例如"dataDisplay":

dataDisplay: Array<object> = this.info;

在 Ionic 生命周期更改期间设置此变量,例如 ionViewWillEnter 或每当设置 this.info 时。

然后换出setFilteredItems()中的变量:

setFilteredItems() {
    this.dataDisplay = this.filterItems(this.searchTerm);
}

现在将您的 *ngFor 更改为新变量:

*ngFor="let data of dataDisplay"

这应该可以解决问题,因为现在 filterItems(searchTerm) 始终过滤完整的原始 this.info 数据集。