Angular 2 ngFor - обратный порядок вывода с использованием индекса

Пытаюсь узнать что-то о фильтрации и упорядочении в Angular 2. Кажется, я не могу найти достойных ресурсов, и я застрял в том, как упорядочить вывод ngFor в обратном порядке с использованием индекса. Я написал следующий канал, поместив его, он продолжает выдавать мне ошибки, что срез массива не является функцией.

@Pipe({
    name: 'reverse'
})
export class ReversePipe implements PipeTransform {
    transform(arr) {
        var copy = arr.slice();
        return copy.reverse();
    }
}

и мой ngfor выглядит так.

<div class="table-row generic" *ngFor="let advert of activeAdverts | reverse let i = index;" [attr.data-index]="i" (click)="viewAd(advert.title)">      
    <div class="table-cell white-text">{{ i+1 }}</div>                    
    <div class="table-cell white-text">{{advert.title}}</div>
    <div class="table-cell green-text">{{advert.advert}}</div>
</div>

person Hamburgersn Heroin    schedule 15.11.2016    source источник
comment
Если вы получаете ошибки, пожалуйста, поделитесь ими в своем вопросе.   -  person Günter Zöchbauer    schedule 15.11.2016
comment
у вас есть синтаксические ошибки?   -  person Roman C    schedule 15.11.2016
comment
Я думаю, вам нужно добавить if(!ar) return;, чтобы не получать ошибок при передаче null.   -  person Günter Zöchbauer    schedule 15.11.2016
comment
в массиве определенно есть элементы. Я получаю вывод, когда удаляю канал из ngfor. Тип ошибок, которые я вижу, - это срез, не являющийся функцией, или реверс, не являющийся функцией.   -  person Hamburgersn Heroin    schedule 15.11.2016
comment
также, точнее, это встроенный шаблон ошибки: 13:47, вызванный: arr.slice не является функцией   -  person Hamburgersn Heroin    schedule 15.11.2016
comment
Вам нужна точка с запятой после ` | реверс`.   -  person    schedule 08.07.2017


Ответы (7)


Для таких распространенных случаев использования я бы посоветовал вам использовать обратный канал из модуля ng-pipes: https://github.com/danrevah/ng-pipes#reverse-1

Из ДОКУМЕНТОВ:

в контроллере:

this.items = [1, 2, 3];

в представлении:

<li *ngFor="let item of items | reverse"> <!-- Array: [3, 2, 1] -->
person D_R    schedule 24.12.2016
comment
Ух ты! он работает даже со списками Observable firebase! - person trojan; 28.08.2017

Я бы еще добавил .slice()

*ngFor="let advert of activeAdverts.slice().reverse() let i = index;"
person Chris Skura    schedule 25.08.2017
comment
Зачем здесь использовать slice()? А если мы не будем делать slice(), что произойдет? - person Satish Patro; 11.02.2019
comment
Reverse() работает на месте. Это означает, что он изменит исходный массив. Срез без параметров возвращает копию activeAdverts, поэтому исходный массив в этом случае остается неизменным. - person Prokhor Sednev; 26.04.2019

Я думаю, что @BhaskerYadav дал лучший ответ. Изменение исходного массива - плохая идея, и его / ее идея не имеет побочных эффектов, производительности или чего-то еще. ИМХО, это просто нуждается в небольшом улучшении, так как все это разыменование индекса нечитаемо в масштабе.

<tr *ngFor="let _ of activeAdverts; let i = index">
  <ng-container *ngIf="activeAdverts[activeAdverts.length-i-1] as advert">
    <td>{{advert.p}}</td>
    <td>{{advert.q}}</td>
    ...
  </ng-container>
</tr>
person Mark Florence    schedule 24.05.2018
comment
Это сработало для меня. Но не понял, что вы подразумеваете под разыменованием индекса, нечитаемым в масштабе. Не могли бы вы помочь объяснить. Спасибо. - person User3250; 07.08.2018
comment
Конечно вещь. Во всех примерах показана всего пара ячеек таблицы. Но это не реально. А если их 10, 20? Если бы вам пришлось писать activeAdverts[activeAdverts.length-i-1] в каждом, ваш шаблон быстро стал бы нечитаемым. Ключевое слово as в *ngIf используется недостаточно, но отлично подходит для создания локальной переменной и присвоения ей выражения *ngIf. Так что в моем примере вам нужно написать длинное разыменование индекса только один раз. - person Mark Florence; 08.08.2018
comment
Ах! Попался. Благодаря тонну! :) - person User3250; 09.08.2018
comment
@MarkFlorence, что, если я динамически нажимаю activeAdverts? - person Chirag; 16.01.2019

Используя следующий метод, вы можете изменить вывод, но исходный массив не будет изменен,

 <tr *ngFor="let advert of activeAdverts; let i = index" >
           <td>{{activeAdverts[activeAdverts.length-i-1]}}</td>
  </tr>
person BhaskerYadav    schedule 08.07.2017

Самый простой способ заставить его работать — просто использовать activeAdverts.reverse(). В твоем случае:

<div class="table-row generic" *ngFor="let advert of activeAdverts.reverse() let i = index;" [attr.data-index]="i" (click)="viewAd(advert.title)">      
    <div class="table-cell white-text">{{ i+1 }}</div>                    
    <div class="table-cell white-text">{{advert.title}}</div>
    <div class="table-cell green-text">{{advert.advert}}</div>
</div>

Я нашел этот ответ, чтобы добиться цели

person Pini Cheyni    schedule 23.08.2017

обратный Lodash работал у меня.

import { reverse} from "lodash";

this.cloudMessages = reverse(this.cloudMessages)
person Sampath    schedule 24.05.2019

Использовать это

*ngFor="let item of items.slice().reverse()"
person Trilok Singh    schedule 01.04.2020