Как изменить порядок элементов в компоненте? Угловой 2+ - PullRequest
0 голосов
/ 05 сентября 2018

Я довольно плохо знаком с Angular, так что это может быть простое исправление.

В настоящее время у меня 3 разные карты, которые вызываются через API. Затем я использую * ngFor, чтобы зациклить эти элементы и создать карту для каждого, как показано ниже:

<div *ngFor="let exploreCard of exploreCards" class="col-sm">
                    <div class="card three-col">
                        <img class="card-img-top" [src]="exploreCard.ImageUrl" alt="Card image cap" />
                        <div class="card-body">
                            <h5 class="card-title">{{exploreCard.Title}}</h5>
                            <p class="card-text">{{exploreCard.Description}}</p>
                            <p>{{exploreCard.Sequence}}</p>
                        </div>
                   </div>
 </div>

Вы увидите, что у меня есть порядковый номер, который распечатан. Сейчас мой json сидит так, что когда API получает его, он возвращается в порядке 3 , 2 , 1.

Я бы хотел вернуть его в порядке 1 , 2 , 3. Однако я знаю, что могу использовать трубу, но мне нужно, чтобы она работала как можно быстрее. Я также не хочу просто изменять порядок возвращенных товаров, потому что это не подходит для будущих дополнений.

Это код в моем компоненте, который запускается при инициализации:

this.exploreService.getExploreCards()
            .subscribe(z => {
                this.exploreCards = z;
                if (this.exploreCards != null && this.exploreCards.length > 0) {
                    this.showLoader = false;
                }
            })

и exploreCards выглядит так:

private exploreCards: ExploreCard[];

Кто-нибудь знает, как добиться правильного упорядочения с помощью логики в компоненте?

Заранее спасибо.

EDIT:

Вот мой getExploreCards() метод:

public getExploreCards(): BehaviorSubject<ExploreCard[]> {
        if (this.exploreCards === null) {
            this.exploreCards = new BehaviorSubject<ExploreCard[]>(null);
            this.http.get(`${this.baseUrl}api/Explore/GetExploreCards`).pipe( 
                retry(3) 
            )
                .subscribe((x: ExploreCard[]) => this.exploreCards.next(x));

        }
        return this.exploreCards;
    }

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Вы можете сортировать карточки, когда извлекаете их из сервиса:

this.exploreService.getExploreCards()
            .subscribe(z => {
                if(z != null) {
                    this.exploreCards = z.sort((a,b) => a.Sequence - b.Sequence);
                }
            })

Или когда карточки должны быть всегда отсортированы, я бы поместил сортировку в сервис.

Или вы можете написать трубу сортировки;)

Вы также можете использовать некоторую служебную функцию вместо нативного javascript, например. из lodash для сортировки по свойству:

_.sortBy(cards, card => card.Sequence );

кстати. Вы не должны устанавливать this.showLoader = false; в подписке, а в finally операторе, чтобы ваш загрузчик больше не был виден при сбое вызова службы.

0 голосов
/ 05 сентября 2018

Не следует делать это в компоненте, но в методе getExploreCards():

getExploreCards(): Observable<ExploreCard[]> {
  this.http.get('link/to/cards').pipe(
    tap((cards) => cards.sort((a, b) => a.Sequence - b.Sequence))
  )
}

Кроме того, подумайте об использовании канала async, это избавит от необходимости отписываться в ваших компонентах. В противном случае у вас будут зависать подписки, а с ней и утечка памяти. Например, это будет ваш HTML тогда:

<div *ngIf="!(exploreCards$ | async)" class="loader"></div>

<div *ngFor="let exploreCard of exploreCards$ | async" class="col-sm">
 <!-- the rest -->
</div>

и ваш тс будет такой:

readonly exploreCards$: Observable<ExploreCard[]> = this.exploreService.getExploreCards();

Но это все зависит от вас:)

- редактировать -

Чтобы обновить ваш метод и иметь немного более простую логику, можно использовать оператор shareReplay() из rxjs:

private exploreCards = this.http.get(`${this.baseUrl}api/Explore/GetExploreCards`).pipe( 
  retry(3),
  tap((cards) => cards.sort((a, b) => a.Sequence - b.Sequence)),
  shareReplay() 
)

public getExploreCards(): Observable<ExploreCard[]> {
  return this.exploreCards;
}

Если вы настаиваете на использовании BehaviourSubject, вы можете использовать это:

public getExploreCards(): BehaviorSubject<ExploreCard[]> {
  if (this.exploreCards === null) {
    this.exploreCards = new BehaviorSubject<ExploreCard[]>(null);
    this.http.get(`${this.baseUrl}api/Explore/GetExploreCards`).pipe( 
      retry(3),
      tap((cards) => cards.sort((a, b) => a.Sequence - b.Sequence)) 
    ).subscribe((x: ExploreCard[]) => this.exploreCards.next(x));
  }

  return this.exploreCards;
}

Имейте в виду, однако, что это очень «анти-шаблон» и оставляет место для открытых подписок. То, что ваша команда использует это, не означает, что это правильный путь;) только мой 2c.

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