Итак, вот возможный способ сделать это (не полностью) ... И, может быть, я перебрал проблему.
Теперь вместо того, чтобы запрашивать или еще что-то, мы можем сохранить как запрос, так иданные как наблюдаемые.В то время как наблюдаемое хранит исходные значения, мы можем использовать различные допустимые операторы, такие как функции mergeMap
и map
.
Оператор map
позволяет нам изменять значение, выбрасываемое из наблюдаемого, оставляя исходное значениев самом наблюдаемом.mergeMap
позволяет нам эффективно объединить две наблюдаемые.В данном случае это _searchQuery
, а также _items
.Также мы можем избежать подписки на эти наблюдаемые, используя async
канал в нашем шаблоне.
По возможности, я бы посоветовал не использовать подписку.Несмотря на свою полезность, я заметил, что вы никогда не отписывались.Это означает, что подписка останется активной, и, как вы снова и снова будете называть ее функцией initializeItems
, вы будете создавать множество подписок.Хотя технически это не проблема для HTTP-запросов (так как они завершаются самостоятельно), полезно знать / иметь в виду.
Дайте мне знать, если есть что-то еще!
search.ts
import { Component } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { mergeMap, map } from 'rxjs/operators';
import { NavController } from 'ionic-angular';
import { ApiService } from '../../services/api.service';
@Component({
selector: 'page-search',
templateUrl: 'search.html'
})
export class SearchPage {
private _searchQuery: BehaviorSubject<string> = new BehaviorSubject<string>('');
private _items: Observable<any[]>;
constructor(public navCtrl: NavController, private apiService: ApiService) {
this._initializeItems();
}
get items(): Observable<any[]> {
return this._searchQuery.pipe(mergeMap((query: string) => {
return this._items.pipe(map((items: any[]) => {
if (query && query.trim() != '') {
return items.filter((item) => {
return (item['name'].toLowerCase().indexOf(query.toLowerCase()) > -1);
});
} else {
return [];
}
}))
})).asObservable();
}
private _initializeItems() {
this._items = this.apiService.productsCall()
.pipe(map((response) => {
if (response['status'] == 200) {
return response['response'];
} else if (response['status'] == 500) {
console.log(response['error'].sqlMessage);
return [];
}
}));
}
public updateQuery(ev: any) {
// set val to the value of the searchbar
const val: string = ev.target.value;
this._searchQuery.next(val);
}
}
search.html
<ion-content padding>
<ion-searchbar (ionInput)="updateQuery($event)"></ion-searchbar>
<ion-list no-lines>
<ion-item *ngFor="let item of items | async">
<ion-label>{{item.name}}</ion-label>
<ion-avatar item-right>
<img src='../assets/imgs/medicalStore.png'>
</ion-avatar>
<ion-checkbox item-left></ion-checkbox>
</ion-item>
</ion-list>
</ion-content>