У меня есть приложение Ionic 4, где я извлекаю данные из API. На странице есть список элементов с бесконечной прокруткой. Теперь я хочу добавить функцию поиска, которая обновит результирующий набор искомым элементом и, при необходимости, сохранит функцию бесконечной прокрутки, если в результатах поиска более 10 элементов.
С кодом ниже я могу просматривать художников и загружать больше с бесконечной прокруткой. Когда я выполняю поиск по имени, появляются правильные результаты, но он пытается загрузить страницу 2 конечной точки элементов без поискового запроса вместо загрузки второй страницы сообщений, где поисковый запрос содержит более 10 результатов.
Я мог бы поставить проверку, имеет ли searchTerm значение при выполнении функции loadItems, но это просто кажется неправильным.
Как я могу обновить элементы и остановить выполнение бесконечной прокрутки, если результатов поиска меньше 10?
Если результатов больше 10, как я могу запустить огонь прокрутки inifinte с конечной точкой поиска?
Я чувствую, что, возможно, я не использую наблюдаемые в полном объеме или неправильно здесь, но я все еще изучаю их, так что будьте спокойны.
Мой код ниже
Items.html
<ion-content padding>
<ion-searchbar [(ngModel)]="searchTerm" (ionChange)="searchChanged($event)"></ion-searchbar>
<ion-grid *ngIf="items">
<ion-row>
<ion-col *ngFor="let item of items">
<app-item-card [item]="item"></app-item-card>
</ion-col>
<ion-infinite-scroll threshold="100px" (ionInfinite)="loadItems($event)">
<ion-infinite-scroll-content loadingSpinner="bubbles" loadingText="Loading more items...">
</ion-infinite-scroll-content>
</ion-infinite-scroll>
</ion-row>
</ion-grid>
</ion-content>
Items.page.ts
import { ItemsService } from '../../services/items.service';
import { Item } from '../../models/item.model';
@Component({
selector: 'app-items',
templateUrl: './items.page.html',
styleUrls: ['./items.page.scss'],
})
export class ItemsPage implements OnInit {
public items: Item[] = [];
public searchTerm: string = '';
constructor(private itemsService: ItemsService) {}
async ngOnInit() {
this.getItems().subscribe(data => {
this.items = data;
});
}
getItems() {
return this.itemsService.getItems();
}
loadItems(event) {
// Calculate the page number to request based on the number of posts
let page = (Math.ceil(this.items.length / 10)) + 1;
this.itemsService.getItems(page).subscribe(data => {
for (let post of data) {
this.items.push(post);
}
event.target.complete();
if (data.length < 10) {
event.target.disabled = true;
}
});
}
searchChanged() {
if (this.searchTerm) {
this.itemsService.searchItems(this.searchTerm).subscribe(data => {
this.items = data;
});
}
}
}
ItemsService.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, forkJoin, of, empty } from 'rxjs';
import { catchError, map, flatMap } from 'rxjs/operators';
import { Item} from '../../models/item.model';
@Injectable({
providedIn: 'root'
})
export class ItemsService {
private apiUrl: string = appConfig.apiUrl;
constructor(private httpClient: HttpClient) { }
getItems(page: number = 1): Observable<Item[]> {
let url = this.apiUrl + 'items/?&page=' + page;
return this.httpClient.get(url).pipe(
map(items => {
let itemsArray = [];
Object.keys(items).forEach(function (key) {
itemsArray.push(new Item(items[key]));
});
return itemsArray;
}),
catchError(val => of(val))
);
}
searchItems(term: string, page: number = 1) {
let url = this.apiUrl + 'items/?page=' + page + '&name=' + encodeURI(term);
return this.httpClient.get(url).pipe(
map((items: Item[]) => {
let itemsArray = [];
Object.keys(items).forEach(function (key) {
itemsArray.push(new Item(items[key]));
});
return itemsArray;
}),
catchError(val => of(val))
);
}
}
Item.model.ts
export class Item {
id: number;
name: string;
constructor(values: Object = {}) {
Object.assign(this, values);
}
}