如何使用自定义管道在Angular中按属性值对对象数组进行排序?

时间:2019-02-12 11:34:48

标签: angular typescript

我需要在Angular中编写一个自定义管道,该管道接受对象数组和名为orderascending的变量descending作为参数,然后对按属性值排列的对象数组。

数据看起来像这样:

[
    {
        "location_type": "KAUPPA",
        "postalcode": "100",
        "availability": "LIIKETILAN AUKIOLO",
        "location": "SUOMALAINEN KIRJAKAUPPA / SISÄKÄYTÄVÄ",
        "municipality": "TURKU",
        "target_address": "ALEKSANTERINKATU 23",
        "availability_details": "",
        "coordinates_lon": "24.941095",
        "coordinates_lat": "60.168718"
    },
    {
        "location_type": "PANKIN KONTTORI",
        "postalcode": "100",
        "availability": "ITSEPALVELUALUEEN AUKIOLO",
        "location": "NORDEA SENAATINTORI",
        "municipality": "VANTAA",
        "target_address": "ALEKSANTERINKATU 30",
        "availability_details": "ma-su klo 06-22",
        "coordinates_lon": "24.950720",
        "coordinates_lat": "60.168930"
    },
    {
        "location_type": "TAVARATALO",
        "postalcode": "100",
        "availability": "LIIKETILAN AUKIOLO",
        "location": "STOCKMANN / 8. KERROS",
        "municipality": "HELSINKI",
        "target_address": "ALEKSANTERINKATU 52",
        "availability_details": "",
        "coordinates_lon": "24.941870",
        "coordinates_lat": "60.168430"
    }
]

需要根据municipality的值对数组中的对象进行排序。

2 个答案:

答案 0 :(得分:3)

正如《评论》中多次提到的,以及Pardeep的上述答案,使用Pipe对数据进行排序也不是一个好主意。

如果要对字段进行排序,只需在模板上实现它,然后仅对事件触发排序功能。这将大大节省您的性能。

在这里,尝试一下:

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  lastSortedByField;
  ascendingOrder = true;
  data = [
    {
      "location_type": "KAUPPA",
      "postalcode": "100",
      "availability": "LIIKETILAN AUKIOLO",
      "location": "SUOMALAINEN KIRJAKAUPPA / SISÄKÄYTÄVÄ",
      "municipality": "TURKU",
      "target_address": "ALEKSANTERINKATU 23",
      "availability_details": "",
      "coordinates_lon": "24.941095",
      "coordinates_lat": "60.168718"
    },
    {
      "location_type": "PANKIN KONTTORI",
      "postalcode": "100",
      "availability": "ITSEPALVELUALUEEN AUKIOLO",
      "location": "NORDEA SENAATINTORI",
      "municipality": "VANTAA",
      "target_address": "ALEKSANTERINKATU 30",
      "availability_details": "ma-su klo 06-22",
      "coordinates_lon": "24.950720",
      "coordinates_lat": "60.168930"
    },
    {
      "location_type": "TAVARATALO",
      "postalcode": "100",
      "availability": "LIIKETILAN AUKIOLO",
      "location": "STOCKMANN / 8. KERROS",
      "municipality": "HELSINKI",
      "target_address": "ALEKSANTERINKATU 52",
      "availability_details": "",
      "coordinates_lon": "24.941870",
      "coordinates_lat": "60.168430"
    }
  ];

  sortByField(field) {
    if(this.lastSortedByField === field) {
      this.ascendingOrder = !this.ascendingOrder;
    }
    else {
      this.lastSortedByField = field;
      this.ascendingOrder = true;
    }

    if(this.ascendingOrder) {
      this.data = this.data.sort((a, b) => {
        if (a[field] < b[field])
          return -1;
        if (a[field] > b[field])
          return 1;
        return 0;
      });
    } else {
      this.data = this.data.sort((a, b) => {
        if (a[field] < b[field])
          return 1;
        if (a[field] > b[field])
          return -1;
        return 0;
      });
    }

  }

}

在模板中:

<table border="1">
  <thead>
    <tr>
      <td (click)="sortByField('location_type')">location_type</td>
      <td (click)="sortByField('postalcode')">postalcode</td>
      <td (click)="sortByField('availability')">availability</td>
      <td (click)="sortByField('location')">location</td>
      <td (click)="sortByField('municipality')">municipality</td>
      <td (click)="sortByField('target_address')">target_address</td>
      <td (click)="sortByField('availability_details')">availability_details</td>
      <td (click)="sortByField('coordinates_lon')">coordinates_lon</td>
      <td (click)="sortByField('coordinates_lat')">coordinates_lat</td>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let datum of data">
      <td>{{ datum.location_type }}</td>
      <td>{{ datum.postalcode }}</td>
      <td>{{ datum.availability }}</td>
      <td>{{ datum.location }}</td>
      <td>{{ datum.municipality }}</td>
      <td>{{ datum.target_address }}</td>
      <td>{{ datum.availability_details }}</td>
      <td>{{ datum.coordinates_lon }}</td>
      <td>{{ datum.coordinates_lat }}</td>
    </tr>
  </tbody>
</table>

  

这是您推荐的Working Sample StackBlitz

答案 1 :(得分:1)

  

官方文档-过滤尤其是排序是昂贵的操作。

     

Angular团队和许多经验丰富的Angular开发人员强烈建议将过滤和排序逻辑移入组件本身。

通常,在这种情况下无需使用自定义管道,而是可以将数据直接排序到组件类中。但是,如果您想使用(?=\D*\d{2,})(?=[^a-z]*[a-z]{5,}),请参考以下内容-

pipe

Working example