如何使用 Angular2 管道按离今天最近的日期排序

How to order by closest date to today using Angular2 pipe

假设我有一个 Event 集合:

export class Event {
  startingTime: Date
}

我想显示它们从最接近今天开始的顺序,OrderByUpcomingToLatestPipe 会是什么样子?

<event-element *ngFor="let event of events | orderByUpcomingToLatest"></event-element>

编辑:

我想让数组降序排列,离今天最近的日期在前,离今天最远的日期在最后(已经过去的日期在远的之后排序相同方式)

不要使用管道进行排序。来自 Pipes documentation 的片段:

Appendix: No FilterPipe or OrderByPipe

Angular doesn't provide pipes for filtering or sorting lists. Developers familiar with AngularJS know these as filter and orderBy. There are no equivalents in Angular.

This isn't an oversight. Angular doesn't offer such pipes because they perform poorly and prevent aggressive minification. Both filter and orderBy require parameters that reference object properties. Earlier in this page, you learned that such pipes must be impure and that Angular calls impure pipes in almost every change-detection cycle.

您应该对服务或组件中的事件进行排序,可能使用类似 Lodash:

的方式
import * as _ from 'lodash';

this.sortedEvents = _.sortBy(this.events, e => p.startingTime);

然后在您的模板中:

<event-element *ngFor="let event of sortedEvents"></event-element>

尝试使用这个自定义管道

import { Pipe, PipeTransform } from "@angular/core"

@Pipe({
    name: 'OrderByUpcomingToLatestPipe '
})
export class OrderByUpcomingToLatestPipe implements PipeTransform {

    transform(value: any, args?: any): any {
        let newVal = value.sort((a: any, b: any) => {
            let date1 = new Date(a.date);
            let date2 = new Date(b.date);

            if (date1 > date2) {
                return 1;
            } else if (date1 < date2) {
                return -1;
            } else {
                return 0;
            }
        });

        return newVal;
    }

}

Working Plunker

这是工作管道

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

@Pipe({
  name: "upcomingToLatest"
})
export class UpcomingToLatestPipe implements PipeTransform{
  transform(array: any, fieldName: any): any {
    if (array) {
      let now: Date = new Date();

      array.sort((a: any, b: any) => {
        let date1: Date = new Date(a.object[fieldName]);
        let date2: Date = new Date(b.object[fieldName]);

        // If the first date passed
        if(date1 < now){
          // If the second date passed
          if(date2 < now){
            return 0
          } else {
            return 1
          }
        } else {
          // If the second date passed
          if(date2 < now) {
            return -1
          } else if(date1 < date2) {
            return -1
          } else if(date1 > date2) {
            return 1
          } else {
            return 0;
          }
        }
      });
    }

    return array;
  }
}

if 树的快速解释:

  1. 如果第一个日期是过去

    1.1 如果第二个日期是过去的-它们的顺序无关紧要

    1.2 Else,表示第二个在未来,将第二个日期调高

  2. 否则,表示第一个日期在未来

    2.1 如果第二个日期是过去的,则将第一个日期的顺序调高

    2.2 否则,如果第一个日期在第二个日期之前,意味着第一个日期比第二个日期更接近 now,则将第一个日期置于更高的顺序

    2.3 否则,意味着第二个日期比第一个日期更接近now,将第二个日期的顺序调高