Подтвердить что ты не робот

Инвертировать Angular 2 * ngFor

<li *ngFor="#user of users ">
    {{ user.name }} is {{ user.age }} years old.
</li>

Можно ли инвертировать ngFor, чтобы элементы были добавлены снизу вверх?

4b9b3361

Ответ 1

Есть две проблемы с выбранным ответом:

Сначала, канал не заметит модификацию исходного массива, если вы не добавите pure: false в свойства канала.

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

Окончательный код выглядит следующим образом:

import {Pipe} from 'angular2/core';

@Pipe({
  name: 'reverse',
  pure: false
})
export class ReversePipe {
  transform (values) {
    if (values) {
      return values.reverse();
    }
  }
}

Plunker

http://plnkr.co/edit/8aYdcv9QZJk6ZB8LZePC?p=preview

Ответ 2

Вам нужно реализовать настраиваемый канал, который использует обратный метод массива JavaScript:

import { Pipe } from '@angular/core';

@Pipe({
  name: 'reverse'
})
export class ReversePipe {
  transform(value) {
    return value.slice().reverse();
  }
}

Вы можете использовать его так:

<li *ngFor="let user of users | reverse">
    {{ user.name }} is {{ user.age }} years old.
</li>

Не забудьте добавить канал в атрибут pipe вашего компонента.

Ответ 3

Обновление

@Pipe({
  name: 'reverse',
  pure: false
})
export class ReversePipe {
  constructor(private differs:IterableDiffers) {
    this.differ = this._differs.find([]).create(null);
  }

  transform(value) {
    const changes = this.differ.diff(value);
    if(changes) {
      this.cached = value.slice().reverse();
    }
    return this.cached;    
  }
}

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

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

Поэтому различаются только фактическая работа, если некоторые изменения были распознаны и в противном случае возвращают кешированный результат из предыдущего вызова.

оригинальный

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

См. также

Ответ 4

Вы можете просто использовать JavaScript .reverse() в массиве. Не требуется специальное решение angular.

<li *ngFor="#user of users.reverse() ">
   {{ user.name }} is {{ user.age }} years old.
</li>

Подробнее здесь: https://www.w3schools.com/jsref/jsref_reverse.asp

Ответ 5

Это должно сделать трюк

<li *ngFor="user of users?.reverse()">
  {{ user.name }} is {{ user.age }} years old.
</li>

Ответ 6

Использование transform требует PipeTransform:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'reverse',
  pure: false
})

export class ReversePipe implements PipeTransform {
  transform (values: any) {
    if (values) {
      return values.reverse();
    }
  }
}

Назовите его <div *ngFor="let user of users | reverse">

Ответ 7

Если кто-то использует typescript, вот как мне удалось заставить его работать, используя ответ @Günter Zöchbauer.

@Pipe({
  name: 'reverse',
  pure: false
})
export class ReversePipe implements PipeTransform {

  differs: any
  cashed: any
  constructor(private _differs: IterableDiffers) {
    this.differs = this._differs.find([]).create(null);
  }
  /**
   * Takes a value and makes it lowercase.
   */
  transform(value, ...args) {
    const changes = this.differs.diff(value)
    if (changes) {
      this.cashed = value.slice().reverse();;
    };
    return this.cashed
  }
}