Как я могу обновить наблюдаемую с данными результатов поиска в приложении Ionic 4 - PullRequest
0 голосов
/ 14 мая 2019

У меня есть приложение 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);
    }
}
...