倒角2 * ngFor

Invert Angular 2 *ngFor

1
2
3
4
<li *ngFor="#user of users">
    {{ user.name }} is {{ user.age }} years old.

</li>

是否可以将ngFor项倒置添加?


您可以简单地在数组上使用JavaScript的.reverse()。不需要特定于angular的解决方案。

1
2
3
4
<li *ngFor="#user of users.slice().reverse()">
   {{ user.name }} is {{ user.age }} years old.

</li>

在此处查看更多信息:
https://www.w3schools.com/jsref/jsref_reverse.asp


您需要实现一个自定义管道,该管道利用JavaScript数组的反向方法:

1
2
3
4
5
6
7
8
9
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'reverse' })

export class ReversePipe implements PipeTransform {
  transform(value) {
    return value.slice().reverse();
  }
}

您可以这样使用它:

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

</li>

别忘了在组件的管道属性中添加管道。


这应该可以解决问题

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

</li>


所选答案有两个问题:

首先,除非将pure: false添加到管道的属性中,否则管道将不会注意到源数组的修改。

第二,管道不支持双向绑定,因为数组的副本是反向的,而不是数组本身。

最终代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
    import {Pipe} from 'angular2/core';

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

柱塞

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


更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@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更改检测仅比较数组实例更改。

为使每次调用更改检测被调用的管道,我使管道不纯。
不纯净的管道会经常被调用,因此有效地工作很重要。
创建一个数组的副本(甚至可能是一个大数组),然后反转其顺序是非常昂贵的。

因此,仅在识别出某些更改后才做实际工作,否则返回上一次调用的缓存结果。

原始

您可以创建一个自定义管道,该管道以相反的顺序返回数组,或者仅以相反的顺序提供数据。

另请参阅

  • angular2排序和过滤器
  • https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse


尝试:

1
2
3
4
5
6
7
<ul>

  <li *ngFor="let item of items.slice().reverse()">{{item}}
</li>


</ul>


一个人可以使用ngx-pipes

npm安装ngx-pipes-保存

模块

1
2
3
4
5
6
7
8
9
import {NgPipesModule} from 'ngx-pipes';

@NgModule({
 // ...
 imports: [
   // ...
   NgPipesModule
 ]
})

组件

1
2
3
4
5
6
7
8
@Component({
  // ..
  providers: [ReversePipe]
})
export class AppComponent {
  constructor(private reversePipe: ReversePipe) {
  }
}

然后在模板

中使用


您可以使用javascript函数进行操作。

1
2
3
4
<li *ngFor="user of users?.slice()?.reverse()">
    {{ user.name }} is {{ user.age }} years old.

</li>

在模板中使用.slice().reverse()的解决方案简单有效。但是,使用迭代索引时应格外小心。

这是因为.slice()方法为视图返回一个新数组,因此我们的初始数组不会更改。问题在于,反向数组也具有反向索引。

因此,如果要将索引用作变量,还应该反转索引。示例:

1
2
3
4
5
6
7
<ul>

  <li *ngFor="let item of items.slice().reverse(); index as i" (click)="myFunction(items.length - 1 - i)">{{item}}
</li>


</ul>

在上面,我们使用与之相反的items.length - 1 - i代替了i,以便单击的项与初始数组的同一项相对应。

检查此堆叠闪电:
https://stackblitz.com/edit/angular-vxasr6?file=src/app/app.component.html


使用transform需要PipeTransform

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    import { Pipe, PipeTransform } from '@angular/core';

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

调用


如果有人在使用typescript,这就是我使用@GünterZ?chbauer的答案设法使其工作的方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@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
  }
}