Как пройти через API с несколькими страницами?

Я вытаскиваю список аудитории из api. Важное замечание касается только 10 аудиторий на каждую страницу показывает. Другими словами, мне нужно перебирать несколько страниц, чтобы просматривать / проверять информацию для всех аудиторий. Как это сделать?

Вот как теперь выглядит этот вытягивающий список из api:

Список аудитории component.ts:

export class NanoAudienceListComponent implements OnInit {

public audienceListDto: AudienceListDto;
public audienceListDtoData: AudienceListDtoData;

constructor(private audienceModel: AudienceModel,
            private modalModel: ModalModel) {
}

public ngOnInit() {
    this.getListDto();
    this.getListDtoData();
}

private getListDto(): void {
    this.audienceListDto = this.audienceModel.getListDto();
}

private getListDtoData(): void {
    this.audienceModel
        .getListDtoData(this.audienceListDto)
        .catch(error => console.info(error))
}

}

Модель аудитории, в которой мы отправляем api req:

    @Injectable()
    export class AudienceModel extends AbstractEntityModel {

    public static ENTITY_NAME: string = 'audience';

    public dto: { [key: string]: AudienceDto };
    public dtoList: Array<AudienceDto>;

    protected entityName = 'Audience';
    protected list: AudienceListDto | null = null;

    protected service: AudienceService;

    constructor(audienceService: AudienceService) {
        super(dialogModel, notificationModel, audienceService, errorHandler);
    }

    public getListDtoDataFromApiByEntity(audienceListDto: AudienceListDto): Promise<any[]> {
        return this.service.getList();
    }
}

Аудитория:

export class AudienceService { 
public getList(...args): Promise<any> {
    return this.http
        .get(this.listUrl, {headers: this.requestHeaders.getHeaders()})
        .toPromise()
        .then(response => response.json());
}

}

Список компонентов html:

 <nano-table *ngIf = "audienceListDto.isLoaded === true"
            [@fadeIn] = "'in'"
            [tableList] = "audienceListDto.list"
            [columnsArray] = "columnsArray"
            [pageCount] = "10"
            [sortField] = "'latestGeneralUploadUniqueUsers'"
            [sortInverse] = "true">
    <ng-template let-audienceListDtoData = "item">
        <div class = "nano-table-entity-name-cell">
            <span [tooltip] = "audienceListDtoData.name"
                  [routerLink] = "['/private/audience/' + audienceListDtoData.id]"
                  class = "nano-c-p">
                {{ audienceListDtoData.name }}
            </span>
            <span>
                {{ audienceListDtoData.id }}
            </span>
        </div>
        <div>
            <span [hidden] = "audienceListDto.areStatisticsLoaded === false">
                {{ audienceListDtoData.dateRange }}
            </span>
        </div>

Компонент таблицы ts: (эта композиция вызывается в компоненте List, и у них есть родительские дочерние отношенияhp)

export class NanoTableComponent {

@ContentChild(TemplateRef) template: TemplateRef<any>;

@Input() columnsArray: Array<NanoTableHeader> = [];
@Input() isAsync: boolean = false;
@Input() nanoTable: NanoTable;
@Input() pageCount: number = 10;
@Input() pageCountOptions: Array<number> = [5, 10, 20];
@Input() sortField: string | null = null;
@Input() sortInverse: boolean = false;
@Input() useQueryParams: boolean = true;
@Input() hasExport: boolean = false;


@Input()
public set tableList(value: Array<any>) {
    this._tableList = value;
    this.onTableListChange();
}

public get tableList(): Array<any> {
    return this._tableList;
}

@Output() paginationChange = new EventEmitter();
@Output() exportRequest = new EventEmitter();

public isExportInProgress: boolean = false;
public isLoadingAsync: boolean = false;

public pageNumber: number = 1;
public searchWord: string = '';

private _tableList: Array<any> = [];

constructor(private router: Router,
            private activatedRoute: ActivatedRoute) {
}

public getFilteredList() {
    if (this.isAsync === true) {
        return this._tableList.slice(0, this.pageCount);
    }
    if (this.pageNumber > Math.ceil(this.filterListBySearchWord().length / this.pageCount)) {
        this.pageNumber = 1;
    }
    return this.filterListBySearchWord().slice((this.pageNumber - 1) * this.pageCount, (this.pageNumber - 1) * this.pageCount + this.pageCount);
    // TODO: Change this.
}

public getLengthForFooter(): number {
    if (this.isAsync) {
        return this.nanoTable.total;
    } else {
        if (this.searchWord) {
            return this.filterListBySearchWord().length;
        }
        return this.tableList.length;
    }
}

public exportReport(): void {
    this.isExportInProgress = true;
    this.exportRequest.emit();
}

public onPageCountChange(pageCount: number): void {
    if (this.isAsync === false) {
        this.pageCount = pageCount;
        // this.filterList();
    } else {
        this.nanoTable.pageCount = pageCount;
    }
    this.onPaginationChange();
}

public onPageNumberChange(pageNumber: number): void {
    if (this.isAsync === false) {
        this.pageNumber = pageNumber;
        // this.filterList();
    } else {
        this.nanoTable.pageNumber = pageNumber;
    }
    this.onPaginationChange();
}

public onSortFieldChange(sortFiled: string) {
    if (this.isAsync === false) {
        this.sortField = sortFiled;
        if (this.sortField === sortFiled) {
            this.sortInverse = !this.sortInverse;
        }
        this.handleColumnSorting(this.sortField);
    } else {
        this.nanoTable.sortField = sortFiled;
        if (this.nanoTable.sortField === sortFiled) {
            this.nanoTable.sortInverse = !this.nanoTable.sortInverse;
        }
    }
    this.onPaginationChange();
}

private checkAreQueryParamsValid(): boolean {
    return Object.keys(this.getQueryParams()).includes('pageCount');
    // TODO: Fix this.
}

private filterListBySearchWord(): Array<any> {
    if (!this.searchWord) {
        return this._tableList;
    }
    let keys: Array<string> = Object.keys(this.tableList[0]);
    return this._tableList.filter((value: { [key: string]: string | number | null }) => {
        for (let i = 0; i < keys.length; i++) {
            if (value[keys[i]] && value[keys[i]].toString().toLowerCase().includes(this.searchWord.toLowerCase())) {
                return true;
            }
        }
        return false;
    });
}

private getQueryParams(): Params {
    return this.activatedRoute.snapshot.queryParams;
}

private handleColumnSorting(column: string): void {
    if (column === null) {
        return;
    }
    let compare = this.sortInverse ? compareReversed : compareNormal;

    function compareNormal(a, b) {
        if (a[column] === null) {
            return 1;
        }
        if (b[column] === null) {
            return -1;
        }
        if (a[column] < b[column]) {
            return -1;
        }
        if (a[column] > b[column]) {
            return 1;
        }
        return 0;
    }

    function compareReversed(a, b) {
        if (a[column] === null) {
            return -1;
        }
        if (b[column] === null) {
            return 1;
        }
        if (a[column] > b[column]) {
            return -1;
        }
        if (a[column] < b[column]) {
            return 1;
        }
        return 0;
    }

    this._tableList.sort(compare);
}

private onPaginationChange(): void {
    this.setQueryParams();
    if (this.isAsync) {
        this.isLoadingAsync = true;
        this.paginationChange.emit(this.nanoTable);
    }
}

private onTableListChange(): void {
    if (this.isAsync === true) {
        this.setTableParams();
    } else {
        this.setFromQueryParams();
        this.handleColumnSorting(this.sortField);
    }
}

private setFromQueryParams(): void {
    if (this.useQueryParams === true && this.checkAreQueryParamsValid()) {
        const queryParams = this.getQueryParams();
        this.pageCount = parseInt(queryParams['pageCount'], 10);
        this.pageNumber = parseInt(queryParams['pageNumber'], 10);
        this.sortField = queryParams['sortField'];
        this.sortInverse = queryParams['sortInverse'] === 'true';
    }
}

}

HTML-часть табличного компонента:

div *ngIf = "tableList.length > 0"
 class = "nano-table-grid nano-mt-5">

<div class = "nano-f-r">
    <input type = "text" [(ngModel)] = "searchWord" class = "nano-white-smoke-input" placeholder = "Search"/>
    <button *ngIf = "hasExport === true && isExportInProgress === false"
            type = "button"
            class = "nano-f-250 nano-white-smoke-button nano-ml-2"
            (click) = "exportReport()">
        <span>
            CSV
        </span>
    </button>
    <nano-loading-indicator *ngIf = "isExportInProgress === true"
                            class = "nano-loading-bar-small nano-loading-bar-overlay nano-f-250 "
                            style = "margin-left: 2px"></nano-loading-indicator>
</div>

<div class = "nano-table-row nano-table-grid-header">
    <div class = "{{column.columnClass}}"
         *ngFor = "let column of columnsArray"
         [ngClass] = "{'sort-active':sortField === column.columnField}"
         (click) = "onSortFieldChange(column.columnField)">
        <span>
            {{column.columnName}}
        </span>
        <i class = "fa"
           [class.fa-sort-asc] = "sortInverse === true && sortField === column.columnField"
           [class.fa-sort-desc] = "sortInverse === false && sortField === column.columnField">
        </i>
    </div>
</div>

У API нет параметров, в которых можно указать диапазон страниц? Если всегда ровно 10 результатов, можете ли вы это изменить? Если у вас нет контроля над API, откуда вы знаете, что достигли последней аудитории в коллекции?

Shilly 07.06.2018 15:02

Где взять количество страниц?

TheUnreal 07.06.2018 15:07

@TheUnreal Я не знаю. В таблице, в которой я должен представить эти данные, по умолчанию 10 элементов на странице.

James Delaney 07.06.2018 15:10

@Shilly Я думаю, что у меня нет этого параметра api на api, на котором я могу указать диапазон страниц. Но сейчас проверю.

James Delaney 07.06.2018 15:13

@Shilly Можно ли изменить текущую реализацию на ту, где я буду перебирать несколько страниц? Потому что вообще проблема в том, что в этом списке аудитории отсутствует пара аудиторий. И я исследую, в чем может быть проблема. Я обнаружил, что это решение может быть итерацией через API с несколькими страницами.

James Delaney 07.06.2018 15:24

Я не знаю, все зависит от того, что предлагает вам API, который вы используете. То, что вы описываете, является простым циклом или параметром, который вы должны добавить, чтобы это было вполне возможно, но без дополнительной информации я не знаю, что может делать API или какие изменения необходимо внести, чтобы использовать API. Поэтому, если вы не свяжете нас с документацией по API, мы не сможем сказать, какие строки кода нужно изменить. Если он ограничен 10 результатами на запрос, ДОЛЖЕН быть параметр или другой механизм для разбивки данных на страницы, иначе API не работает. Но если это this.listUrl + '&page=4' или this.listURL + '&range=4-5', то только вы можете нам сказать.

Shilly 07.06.2018 15:27

@Shilly Хорошо, спасибо! В настоящее время у меня не так много информации, но вы помогли мне здесь лучше понять, что мне нужно делать.

James Delaney 07.06.2018 15:30

@Shilly, хорошо, спасибо! Мне нужно время, чтобы разобраться.

James Delaney 07.06.2018 15:31
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
8
100
0

Другие вопросы по теме