<li *ngFor="#user of users ">
{{ user.name }} is {{ user.age }} years old.
</li>
Можно ли инвертировать ngFor, чтобы элементы были добавлены снизу вверх?
<li *ngFor="#user of users ">
{{ user.name }} is {{ user.age }} years old.
</li>
Можно ли инвертировать ngFor, чтобы элементы были добавлены снизу вверх?
Есть две проблемы с выбранным ответом:
Сначала, канал не заметит модификацию исходного массива, если вы не добавите pure: false
в свойства канала.
Второй, канал не поддерживает двунаправленную привязку, потому что копия массива обращена вспять, а не сам массив.
Окончательный код выглядит следующим образом:
import {Pipe} from 'angular2/core';
@Pipe({
name: 'reverse',
pure: false
})
export class ReversePipe {
transform (values) {
if (values) {
return values.reverse();
}
}
}
Вам нужно реализовать настраиваемый канал, который использует обратный метод массива 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 вашего компонента.
Обновление
@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 изменение обнаружения по умолчанию только сравнивает изменения экземпляра массива.
Для вызова трубки, вызываемой каждый раз, когда происходит обнаружение изменения, я делал трубу нечистой. Нечистая труба будет называться очень часто, поэтому важно, чтобы она работала эффективно. Создание копии массива (возможно, даже большого массива), а затем изменение его порядка довольно дорого.
Поэтому различаются только фактическая работа, если некоторые изменения были распознаны и в противном случае возвращают кешированный результат из предыдущего вызова.
оригинальный
Вы можете создать настраиваемый канал, который возвращает массив в обратном порядке или просто предоставит данные в обратном порядке, в первую очередь.
См. также
Вы можете просто использовать 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
Это должно сделать трюк
<li *ngFor="user of users?.reverse()">
{{ user.name }} is {{ user.age }} years old.
</li>
Использование 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">
Если кто-то использует 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
}
}