ngx-pagination: реализация на Angular 6 на стороне сервера - PullRequest
0 голосов
/ 17 октября 2018

Я пытаюсь использовать ngx-pagination для реализации нумерации на стороне сервера в своем приложении Angular 6.

Я следовал документации в меру своих возможностей, но ястолкнулся со следующими проблемами и не знаю, как действовать.

Проблемы

  1. Компонент загружает и получает данные из API, ноне отображается при рендеринге до после Я бы сделал еще два вызова API, перейдя на следующую страницу, а затем на предыдущую.

  2. Данные на второй страницеAPI не вызывается.

Скриншоты

Начальная загрузка страницы enter image description here

После навигации вперед и назад enter image description here

Пример кода

import { Component, OnInit, Input, ChangeDetectionStrategy } from '@angular/core';
import { Http, Response } from '@angular/http';
import { ApiService } from '../../services/api.service';
import { SiteUrls } from '../../services/constants.service';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import 'rxjs/add/operator/delay';

interface IServerResponse {
    items: any[];
    total: number;
}

@Component({
    selector: 'app-sample',
    templateUrl: './sample.component.html',
    styleUrls: ['./sample.component.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush
})

export class SampleComponent implements OnInit {

    @Input() sample: any = [{}];
    total: number;
    p = 1;
    pagedItems: Observable<any[]>;
    public meta: any = {};
    constructor(private site: SiteUrls, private http: Http, private api: ApiService) {}

    ngOnInit() {
        this.getPage(1);
    }

    async getPage(page: number) {
        this.pagedItems = this.serverCall(this.sample, page)
            .pipe(tap((res) => {
                this.total = res.total;
                this.p = page;
                console.log('total', this.total, 'page', this.p, 'res', res);

            })).pipe(map((res) => res.items));
    }

    serverCall(sample: any[], page: number): Observable<IServerResponse> {
        this.getsample();
        const perPage = this.meta.per_page;
        const start = (page - 1) * perPage;
        const end = start + perPage;
        return of({
                items: sample.slice(start, end),
                total: this.meta.total
            }).delay(1000);
    }

   private getsample() {
        this.api.get('sample').subscribe((data) => {
            this.sample = data.body.data;
            this.meta = data.body.meta;
        });
    }
}
 <tbody>
                <tr *ngFor="let tran of pagedItems | async | paginate: { itemsPerPage: meta.per_page, currentPage: p, totalItems: meta.total }">
                 
                  <td>
                    {{tran.account.number}}
                  </td>
                  <td>
                    {{tran.sender.name}}
                  </td>
                  <td>
                    {{tran.recipient.name}}
                  </td>
                  <td>
                    {{tran.date | date: 'MMMM dd, yyyy'}}
                  </td>
                  <td style="background-color: antiquewhite">
                    {{tran.subtotal | currency}}
                  </td>
                  <td style="background-color: antiquewhite">
                    {{tran.fee | currency}}
                  </td>
                  <td style="background-color: antiquewhite">
                    <b>{{tran.total | currency}}</b>
                  </td>
                </tr>
              </tbody>
            </table>
            <pagination-controls (pageChange)="getPage($event)"></pagination-controls>

Любая помощь приветствуется.

ОБНОВЛЕНИЕ

getsample() выполняется назагрузка страницы и API возвращает данные.В целях безопасности я изменил метод на async, так что теперь он выглядит следующим образом:

async getsample() {
   try {
       await this.api.get('sample').subscribe((data) => {
        this.sample = data.body.data;
        this.meta = data.body.meta;
       });
   } catch (error) {}
  }

Я также реализовал ответ, данный Брэндоном, но проблема все еще сохраняется.

Ответы [ 2 ]

0 голосов
/ 18 октября 2018

Есть еще проблемы с вашим кодом, одна из них - ваш асинхронный вызов this.getsample();, но вы не ждете результата.

Другое дело, что вы не можете ожидать наблюдаемого.Преобразуйте его в обещание сначала через .toPromise() вместо подписки, или вообще не используйте обещания и подписывайте вместо этого (но только на самом верхнем уровне - в обработчике ngOnInit).

Использование async / await:

async ngOnInit() {
    await this.getsample(); // move the loading here
    await this.getPage(1);
}

async getPage(page: number) {
    const res = await this.serverCall(this.sample, page);
    this.total = res.total;
    this.p = page;
    console.log('total', this.total, 'page', this.p, 'res', res);
    this.pagedItems = res.items;
}

async serverCall(sample: any[], page: number): Promise<IServerResponse> {
    const perPage = this.meta.per_page;
    const start = (page - 1) * perPage;
    const end = start + perPage;
    return of({
        items: sample.slice(start, end),
        total: this.meta.total
    }).delay(1000).toPromise(); // convert the observable to promise
}

private async getsample() {
    const data = await this.api.get('sample').toPromise(); // and again here
    this.sample = data.body.data;
    this.meta = data.body.meta;
}
0 голосов
/ 17 октября 2018

Это асинхронная / ожидающая проблема.

ngOnInit() {
  this.getPage(1);
}

должно быть:

async ngOnInit() {
  await this.getPage(1);
}

В противном случае this.pagedItems будет нулевым, пока serverCall() не завершится.

...