简体   繁体   English

在Angular2中对对象数组进行排序

[英]Sort an array of objects in Angular2

I have problems with sorting an array of object in Angular2. 我在Angular2中排序对象数组时遇到问题。

The object looks like: 该对象看起来像:

[
  {
    "name": "t10",
    "ts": 1476778297100,
    "value": "32.339264",
    "xid": "DP_049908"
  },
  {
    "name": "t17",
    "ts": 1476778341100,
    "value": "true",
    "xid": "DP_693259"
  },
  {
    "name": "t16",
    "ts": 1476778341100,
    "value": "true",
    "xid": "DP_891890"
  }
]

And is being stored inside the values variable. 并存储在values变量中。

All I want is to make the *ngFor loop sort it by the name property. 我想要的是让*ngFor循环按name属性对其进行排序。

<table *ngIf="values.length">
    <tr *ngFor="let elem of values">
      <td>{{ elem.name }}</td>
      <td>{{ elem.ts }}</td>
      <td>{{ elem.value }}</td>
    </tr>
</table>

Tried to do it with pipes, but failed miserably. 试图用管子做,但失败了。 Any help appreciated. 任何帮助赞赏。

Plunker link : https://plnkr.co/edit/e9laTBnqJKb8VzhHEBmn?p=preview Plunker链接https//plnkr.co/edit/e9laTBnqJKb8VzhHEBmn p = preview

Edit 编辑

My pipe: 我的烟斗:

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

@Component({
  selector: 'watchlist',
  templateUrl: './watchlist.component.html',
  styleUrls: ['./watchlist.component.css'],
  pipes: [ ArraySortPipe ]
})
@Pipe({
  name: "sort"
})

export class ArraySortPipe implements PipeTransform {
  transform(array: Array<string>, args: string): Array<string> {
    array.sort((a: any, b: any) => {
      if (a < b) {
        return -1;
      } else if (a > b) {
        return 1;
      } else {
        return 0;
      }
    });
    return array;
  }
}

And just put the pipe name into html file: 然后将pipe名称放入html文件:

<tr *ngFor="let elem of values | sort">

Although you can solve this problem with a pipe, you have to ask yourself if the re-usability of a pipe is useful to you in your particular project. 虽然您可以使用管道解决此问题,但您必须问自己,管道的可重用性是否对您的特定项目有用。 Will you often need to sort objects by the "name" key on other arrays or other components in the future? 您是否经常需要通过其他阵列或其他组件上的“名称”键对对象进行排序? Will this data be changing often enough and in ways that make it hard to simply sort in the component? 这些数据是否会经常变化,并且难以简单地对组件进行排序? Will you need the array sorted on any change to the view or inputs? 您是否需要对视图或输入的任何更改进行排序?

I created an edited plunker in which the array is sorted in the component's constructor, but there's no reason this functionality couldn't be moved out into its own method (sortValuesArray for instance) for re-use if necessary. 我创建了一个编辑过的plunker,其中数组在组件的构造函数中进行排序,但是没有理由不能将此功能移出到自己的方法(例如sortValuesArray)中以便在必要时重新使用。

constructor() {
  this.values.sort((a, b) => {
    if (a.name < b.name) return -1;
    else if (a.name > b.name) return 1;
    else return 0;
  });
}

Edited Plunker 编辑Plunker

Try this 试试这个

Sort from A to end of alpahbet: 从A到alpahbet的结尾排序:

this.suppliers.sort((a,b)=>a.SupplierName.localeCompare(b.SupplierName));

Z=>A (reverse order) Z => A(逆序)

this.suppliers.sort((a,b)=>b.SupplierName.localeCompare(a.SupplierName));

Your pipe expects strings but it gets objects, you should adapt it: 您的管道需要字符串,但它获取对象,您应该调整它:

export class ArraySortPipe implements PipeTransform {
  transform(array: Array<any>): Array<string> {
    array.sort((a: any, b: any) => {
      if (a.name < b.name) {
        return -1;
      } else if (a.name > b.name) {
        return 1;
      } else {
        return 0;
      }
    });
    return array;
  }
}

Angular still advice not to use pipes for sorting and filtering, like in angularJs. Angular仍建议不要使用管道进行排序和过滤,例如angularJs。

It will slow down your application, have some performance issues. 它会降低您的应用程序速度,出现一些性能问题。 It is a lot better to provide your sorting in your component before passing it to the template. 在将组件传递给模板之前,在组件中提供排序要好得多。

The reason is explained on https://angular.io/guide/pipes#no-filter-pipe 原因在https://angular.io/guide/pipes#no-filter-pipe上解释

If you work with a nice structured component layout you can do it even on te setter: 如果你使用一个漂亮的结构化组件布局,你甚至可以在te setter上做到这一点:

 @Input()
  set users(users: Array<User>) {
    this.usersResult = (users || []).sort((a: User, b: User) => a.name < b.name ? -1 : 1)
  }

This is adaptable to any such usecase. 这适用于任何此类用例。

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

@Pipe({
  name: 'sortBy'
})
export class SortByPipe implements PipeTransform {
  transform(arr: Array<any>, prop: any, reverse: boolean = false): any {
    if (arr === undefined) return
    const m = reverse ? -1 : 1
    return arr.sort((a: any, b: any): number => {
      const x = a[prop]
      const y = b[prop]
      return (x === y) ? 0 : (x < y) ? -1*m : 1*m
    })
  }
}

Usage:- 用法:-
<div *ngFor="let item of list | sortBy: 'isDir': true">

UPDATE UPDATE
Refer Bo's answer as filtering and sorting in pipes is not recommended. 请参考Bo的答案,因为不建议在管道中进行过滤和排序。

its simple, for example if you have this array object: 它很简单,例如,如果你有这个数组对象:

 cars = ["Dodge", "Fiat", "Audi", "Volvo", "BMW", "Ford"];

and you want to have the object sorted in the HTML front, use: 并且您希望将对象排序在HTML前端,使用:

 <li ng-repeat="x in cars | orderBy">{{x}}</li>

By default, strings are sorted alphabetically, and numbers are sorted numerically. 默认情况下,字符串按字母顺序排序,数字按数字排序。

If you have this array with keys: 如果你有这个带有键的数组:

customers = [
{"name" : "Bottom-Dollar Marketse" ,"city" : "Tsawassen"},
{"name" : "Alfreds Futterkiste", "city" : "Berlin"},
{"name" : "Bon app", "city" : "Marseille"},
{"name" : "Cactus Comidas para llevar", "city" : "Buenos Aires"},
{"name" : "Bolido Comidas preparadas", "city" : "Madrid"},
{"name" : "Around the Horn", "city" : "London"},
{"name" : "B's Beverages", "city" : "London"}
];

Use: 使用:

Sort the array by "city" DESC order: 按“城市”DESC顺序对数组进行排序:

<li ng-repeat="x in customers | orderBy : '-city'">{{x.name + ", " + x.city}}</li>

Sort the array by "city": 按“城市”排序数组:

<li ng-repeat="x in customers | orderBy : 'city'">{{x.name + ", " + x.city}}</li>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM