0

我正在尝试按优先级 [high, medium, low] 对会议进行排序,但我最终按字母顺序 [high, low, medium] 对它们进行排序,那么如何解决这个问题?这是文件:

排序.ts

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

@Pipe({name:'OrderBy',pure:false})

export class OrderBy implements PipeTransform {
static _orderByComparator(a:any, b:any):number{

    if((isNaN(parseFloat(a)) || !isFinite(a)) || (isNaN(parseFloat(b)) || !isFinite(b))){
        //Isn't a number so lowercase the string to properly compare
        if(a.toLowerCase() < b.toLowerCase()) return -1;
        if(a.toLowerCase() > b.toLowerCase()) return 1;
    }
    else{
        //Parse strings as numbers to compare properly
        if(parseFloat(a) < parseFloat(b)) return -1;
        if(parseFloat(a) > parseFloat(b)) return 1;
    }

    return 0; //equal each other
}
transform(input:any, [config = '+']): any{

    if(!Array.isArray(input)) return input;

    if(!Array.isArray(config) || (Array.isArray(config) && config.length == 1)){
        var propertyToCheck:string = !Array.isArray(config) ? config : config[0];
        var desc = propertyToCheck.substr(0, 1) == '-';

        //Basic array
        if(!propertyToCheck || propertyToCheck == '-' || propertyToCheck == '+'){
            return !desc ? input.sort() : input.sort().reverse();
        }
        else {
            var property:string = propertyToCheck.substr(0, 1) == '+' || propertyToCheck.substr(0, 1) == '-'
                ? propertyToCheck.substr(1)
                : propertyToCheck;

            return input.sort(function(a:any,b:any){
                return !desc
                    ? OrderBy._orderByComparator(a[property], b[property])
                    : -OrderBy._orderByComparator(a[property], b[property]);
            });
        }
    }
    else {
        //Loop over property of the array in order and sort
        return input.sort(function(a:any,b:any){
            for(var i:number = 0; i < config.length; i++){
                var desc = config[i].substr(0, 1) == '-';
                var property = config[i].substr(0, 1) == '+' || config[i].substr(0, 1) == '-'
                    ? config[i].substr(1)
                    : config[i];

                var comparison = !desc
                    ? OrderBy._orderByComparator(a[property], b[property])
                    : -OrderBy._orderByComparator(a[property], b[property]);

                //Don't return 0 yet in case of needing to sort by next property
                if(comparison != 0) return comparison;
            }

            return 0; //equal each other
        });
    }
}}

会议.component.ts

import { Component,ChangeDetectionStrategy,Pipe, OnInit }from '@angular/core';
import { Router } from '@angular/router';

import {Meeting} from'./meeting';
import {MeetingService} from '../_services/meeting.service';
import {OrderBy} from './sort';

@Component({
moduleId: module.id,
selector: 'meetings-app',
templateUrl: 'meetings.component.html',
providers:[MeetingService,OrderBy]})

export class MeetingsComponent implements OnInit {

    priority:string[]=[
    'High',
    'Medium',
    'Low'
];
meetings : Meeting[]; //const meeting
selectedmeeting: Meeting; //class}

会议.component.html

<div>
<p>Order by:</p>
<ul>
    <li *ngFor="let o of meetings | OrderBy:['priority']">{{o.title}} {{o.priority}}</li>
</ul>

4

2 回答 2

0

将属性键和指定排名的数组都传递给管道

@Pipe({name: 'orderBy'}) export class OrderByPipe {
  transform<T>(items: T[], key: keyof T, rankings?: Array<T[typeof key]>) {
    const results = items.slice();

    if (rankings) {
      return results.sort(({[key]: leftValue}, {[key]: rightValue}) => {
        const leftRank = rankings.indexOf(leftValue);
        const rightRank = rankings.indexOf(rightValue);
        return leftRank < rightRank ? 1 : leftRank === rightRank ? 0 : -1;
      });
    }
    else {
      return results.sort(({[key]: leftValue}, {[key]: rightValue}) => {
        return String(leftValue).localeCompare(String(rightValue));
      });
    }
  }
}

用法:

<p>Order by:</p>
<ul>
  <li *ngFor="let o of meetings | OrderBy : 'priority' : priority">
    {{o.title}} {{o.priority}}
  </li>
</ul>

由于我们将排名设为可选,因此我们也可以将其用于基本的排序场景。

<p>Order by:</p>
<ul>
  <li *ngFor="let o of meetings | OrderBy : 'title'">
    {{o.title}} {{o.priority}}
  </li>
</ul>
于 2017-05-05T09:47:32.640 回答
0

array.prorotype.sort接受您可以利用的比较功能。

下面的管道可以满足您的期望

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

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

  transform(value: any, ranks: string[], field: string): any {
    const res = value.slice();
    return res.sort((a, b) =>
      ranks.indexOf(a[field].toLowerCase()) -
      ranks.indexOf(b[field].toLowerCase()));
    }
}

在您的模板中使用它,如下所示:

<ul>
  <li *ngFor="let m of meetings | orderByPriority:priority:'priority'">
    {{ m.title }} - {{ m.priority }}
  </li>
</ul>

这是一个使用这个 orderBy 管道的工作 plunkr

于 2017-05-05T09:50:38.220 回答