我已经构建了一个使用搜索栏过滤 *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)
这是因为你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数据集。