如何在 *ngFor 中使用 ionic 4 搜索栏

Tho*_*oot 1 ionic4

我已经构建了一个使用搜索栏过滤 *ngFor 数组的页面。当我在搜索栏中键入时,它的行为正常,但是当我删除或退格文本时,它不会更新。如果我从数据服务的静态列表中提取一个数组,而不是我从 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>
Run Code Online (Sandbox Code Playgroud)

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;
      });
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

Nic*_*nch 5

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

setFilteredItems() {
    //Overwrite this.info with new filtered data set.
    this.info = this.filterItems(this.searchTerm);
}
Run Code Online (Sandbox Code Playgroud)

旧值被过滤掉并且不再存在 - 这就是为什么*ngFor="let data of info"不显示它们。

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

dataDisplay: Array<object> = this.info;
Run Code Online (Sandbox Code Playgroud)

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

然后换出变量setFilteredItems()

setFilteredItems() {
    this.dataDisplay = this.filterItems(this.searchTerm);
}
Run Code Online (Sandbox Code Playgroud)

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

*ngFor="let data of dataDisplay"
Run Code Online (Sandbox Code Playgroud)

这应该对你有用,因为现在filterItems(searchTerm)总是过滤完整的原始this.info数据集。