Листинг + pgination с использованием RXJS Angular - PullRequest
0 голосов
/ 12 декабря 2018

Я только начал небольшой угловой проект, в котором у меня есть компонент Article для перечисления статей с системой нумерации страниц.Страница по умолчанию image

Основные цели:

  • Отображение статей после использования ресурсов GET API.
  • Разбиение статей на статьи с помощью ngb-pagination .

Мой код работает отлично, за исключением того, что я замечаю небольшое обновление страницы каждый раз, когда я разбиваюсь на другую страницу.Это кажется плохой вещью для пользователя.Я уверен, что мой код нуждается в большом количестве улучшений, потому что я новичок в манипулировании RXJS и Observables.

Это мой article.component.ts

import {Component, OnInit} from '@angular/core';
import {HttpClient, HttpParams} from '@angular/common/http';
import {Observable} from 'rxjs';
import {environment} from '../../environments/environment';
import {map} from 'rxjs/internal/operators';
import {Article} from './article.model';
import {ItemResponse} from './item-response.model';
import {ArticleService} from './article.service';

@Component({
  selector: 'app-article',
  templateUrl: './article.component.html',
  styleUrls: ['./article.component.css']
})
export class ArticleComponent implements OnInit {
  public limit = 5;
  public page = 1;
  public total: number;
  public previousPage: number;
  readonly imagePath = `${environment.apiUrl}` + '/..';

  public observable$: Observable<Article[]>;
  public articles: Article[];

  constructor(
    private http: HttpClient,
    private articleService: ArticleService
  ) {
  }

  ngOnInit() {
    this.loadData();
  }

  loadPage(page: number) {
    if (page !== this.previousPage) {
      this.previousPage = page;
      this.loadData();
    }
  }

  loadData() {
    this.observable$ = this.articleService.getArticles(
      new HttpParams()
        .set('page', this.page.toString())
        .set('per_page', this.limit.toString())
    ).pipe(map((res: ItemResponse) => {
      this.page = res.page;
      this.total = res.total;
      this.limit = res.limit;
      return res._embedded.items;
    }));
    this.observable$.subscribe((res: Article[]) => this.articles = res);
  }

  trackElement(index: number, element: any) {
    return element ? element.id : null;
  }

  createRange(len = 6) {
    const arr = [];
    for (let i = 0; i < len; i++) {
      arr.push(i);
    }
    return arr;
  }

Это мой article.service.ts

import { Injectable } from '@angular/core';
import {HttpClient, HttpParams} from '@angular/common/http';
import {environment} from '../../environments/environment';

@Injectable({
  providedIn: 'root'
})
export class ArticleService {
  private _articlesUrl = `${environment.apiUrl}` + '/articles';
  constructor(private http: HttpClient) { }

  getArticles(params?: HttpParams) {
    return this.http.get(this._articlesUrl, {
      params: params
    });
  }
}

это мой article.component.html

<div class="grid" *ngFor="let article of (articles); trackBy: trackElement">
      <div class="entry-media">
        <img appFadeInAnimation class="animated-background"  [src]="imagePath + article.image">
      </div>
     ...
</div>

Вопрос: Как исправить обновление страницы, чтобы оптимизировать загрузку данных?Нужно ли мне уничтожить подписку?

Любая помощь, рекомендации, передовые методы будут оценены и оценены.

1 Ответ

0 голосов
/ 12 декабря 2018

Вы можете сделать это несколькими различными способами.способ, которым я обычно обращаюсь с подобными ситуациями, состоит в том, чтобы разделить на умный компонент и немой компонент.Это отличная статья об этом ( Презентационные и Контейнерные Компоненты .

способ, которым это работает, состоит в том, чтобы передать Observable<Article[]> в тупой компонент, который имеет только одно задание (представляет данные).

<article-items [articles]="articles$ | async"(selectedArticle)="selectedArticle($event)"> </article-items> 

, где

this.articles$ = this.articleService.getArticles(
  new HttpParams()
    .set('page', this.page.toString())
    .set('per_page', this.limit.toString())
).pipe(map((res: ItemResponse) => {
  this.page = res.page;
  this.total = res.total;
  this.limit = res.limit;
  return res._embedded.items;
}));

, таким образом, вам не нужно подписываться на данные (асинхронный канал сделает это автоматически) и не беспокойтесь об отмене подписки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...