OrderBy Pipe Problem

97

Ich kann diesen Code nicht von Angualr 1 nach Angular 2 übersetzen:

ng-repeat="todo in todos | orderBy: 'completed'"

Dies ist, was ich nach der Antwort des Thierry Templier getan habe:

Komponentenvorlage:

*ngFor="#todo of todos | sort"

Komponentencode:

@Component({
    selector: 'my-app',
    templateUrl: "./app/todo-list.component.html",
    providers: [TodoService],
    pipes: [ TodosSortPipe ]

})

Pipe Code:

import { Pipe } from "angular2/core";
import {Todo} from './todo';

@Pipe({
  name: "sort"
})
export class TodosSortPipe {
  transform(array: Array<Todo>, args: string): Array<Todo> {
    array.sort((a: any, b: any) => {
      if (a < b) {
        return -1;
      } else if (a > b) {
        return 1;
      } else {
        return 0;
      }
    });
    return array;
  }
}

Ich versuche, ein Array von Todos zu sortieren , geordnet nach der Eigenschaft completed. Erst todo.completed = falseund dann die todo.complete = true.

Ich verstehe die transformMethode und die Übergabe der Argumente in dieser Methode und in der sortMethode nicht sehr gut .

Was ist das args: stringArgument? Was sind aund bwoher sie kommen?

Alexander Abakumov
quelle
Ich fand dieses Modulpaket für OrderBy in Angular5 + -Versionen freakyjolly.com/…
Code Spy

Antworten:

78

Ich habe die Antwort von @Thierry Templier so geändert, dass die Pipe benutzerdefinierte Objekte in Winkel 4 sortieren kann:

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

@Pipe({
  name: "sort"
})
export class ArraySortPipe  implements PipeTransform {
  transform(array: any, field: string): any[] {
    if (!Array.isArray(array)) {
      return;
    }
    array.sort((a: any, b: any) => {
      if (a[field] < b[field]) {
        return -1;
      } else if (a[field] > b[field]) {
        return 1;
      } else {
        return 0;
      }
    });
    return array;
  }
}

Und um es zu benutzen:

*ngFor="let myObj of myArr | sort:'fieldName'"

Hoffentlich hilft das jemandem.

Sal
quelle
1
Ich habe die Nachricht : The pipe 'sort' could not be found. Kann ich irgendwie Rohr in meine Komponente injizieren, wie in Winkel-2-Rohren: [ArraySortPipe]?
Matija Župančić
Siehe @ Thierry Templier Antwort, wie Sie das Rohr in Ihre App-Komponente injizieren
Sal
Sie müssen "ArraySortPipe" in Ihre Modulhierarchiedeklarationen aufnehmen. So etwas wie: {ArraySortPipe} aus './../../shared/filters.pipe' importieren; In 'app.module.ts' und jedem Modul darunter. put: Deklarationen: [ArraySortPipe]
Dudi
71

Die vollständige Diskussion finden Sie unter https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe . Dieses Zitat ist am relevantesten. Grundsätzlich sollte bei großen Apps, die aggressiv minimiert werden sollten, die Filter- und Sortierlogik auf die Komponente selbst verschoben werden.

"Einige von uns möchten dies möglicherweise nicht aggressiv minimieren. Dies ist unsere Wahl. Das Angular-Produkt sollte jedoch nicht verhindern, dass andere Personen aggressiv minimieren. Daher hat das Angular-Team entschieden, dass alles, was in Angular geliefert wird, sicher minimiert wird.

Das Angular-Team und viele erfahrene Angular-Entwickler empfehlen dringend, die Filter- und Sortierlogik in die Komponente selbst zu verschieben. Die Komponente kann eine Eigenschaft filteredHeroes oder sortedHeroes verfügbar machen und steuern, wann und wie oft die unterstützende Logik ausgeführt werden soll. Alle Funktionen, die Sie in eine Pipe eingefügt und für die gesamte App freigegeben hätten, können in einen Filter- / Sortierservice geschrieben und in die Komponente eingefügt werden. "

Vitali Kniazeu
quelle
7
Wie sollten Sie die Logik "in die Komponente selbst" verschieben, um "die Kontrolle darüber zu übernehmen, wann und wie oft die unterstützende Logik ausgeführt werden soll"? Gibt es gute Beispiele dafür?
Mzzzzzz
1
@Mzzzzzz Wenn eine Eigenschaft wie filteredHeroesund erwähnt wird sortedHeroes, besteht die Idee darin, dass Sie beim Initialisieren der Komponente eine Sortier- / Filterlogik ausführen (möglicherweise eine Methode von ngOnInit aufrufen) und diese Eigenschaft dann mit den sortierten / gefilterten Ergebnissen festlegen Führen Sie die Logik nur erneut aus / aktualisieren Sie die Eigenschaft, wenn etwas einen Bedarf auslöst (z. B. löst eine Benutzerinteraktion einen AJAX-Aufruf aus, um mehr Helden zu erhalten, oder der Benutzer klickt auf ein Kontrollkästchen, um die Hälfte davon nach bestimmten Kriterien usw.
herauszufiltern
41

Sie können hierfür eine benutzerdefinierte Pipe implementieren, die die sortMethode der Arrays nutzt :

import { Pipe } from "angular2/core";

@Pipe({
  name: "sort"
})
export class ArraySortPipe {
  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;
  }
}

Und verwenden Sie dann dieses Rohr wie unten beschrieben. Vergessen Sie nicht, Ihre Pipe im pipesAttribut der Komponente anzugeben :

@Component({
  (...)
  template: `
    <li *ngFor="list | sort"> (...) </li>
  `,
  pipes: [ ArraySortPipe ]
})
(...)

Es ist ein einfaches Beispiel für Arrays mit Zeichenfolgenwerten, aber Sie können eine erweiterte Sortierverarbeitung durchführen (basierend auf Objektattributen im Fall eines Objektarrays, basierend auf Sortierparametern, ...).

Hier ist ein Plunkr dafür: https://plnkr.co/edit/WbzqDDOqN1oAhvqMkQRQ?p=preview .

Hoffe es hilft dir, Thierry

Thierry Templier
quelle
1
Vielen Dank für Ihre Antwort. Können Sie die Sortiermethode erläutern?
1
Tatsächlich ist die sortMethode eine Methode des JavaScript- ArrayObjekts. Siehe diesen Link: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .
Thierry Templier
Ok, ich habe es verstanden, es verwendet die Javascript-Sortiermethode mit einer Vergleichsfunktion als Argument. Danke!
1
Leider ist der Plunker veraltet. Thierry?
4
Die pipes: [..]Erklärung ist nicht mehr gültig (und nicht mehr erforderlich)
phil294
9

Aktualisierte OrderByPipe: Fehler beim Sortieren von Zeichenfolgen behoben.

Erstellen Sie eine OrderByPipe-Klasse:

import { Pipe, PipeTransform } from "@angular/core";
@Pipe( {
name: 'orderBy'
} )
export class OrderByPipe implements PipeTransform {
transform( array: Array<any>, orderField: string, orderType: boolean ): Array<string> {
    array.sort( ( a: any, b: any ) => {
        let ae = a[ orderField ];
        let be = b[ orderField ];
        if ( ae == undefined && be == undefined ) return 0;
        if ( ae == undefined && be != undefined ) return orderType ? 1 : -1;
        if ( ae != undefined && be == undefined ) return orderType ? -1 : 1;
        if ( ae == be ) return 0;
        return orderType ? (ae.toString().toLowerCase() > be.toString().toLowerCase() ? -1 : 1) : (be.toString().toLowerCase() > ae.toString().toLowerCase() ? -1 : 1);
    } );
    return array;
  }
}

in Ihrem Controller:

@Component({
pipes: [OrderByPipe]
})

oder in deinem

 declarations: [OrderByPipe]

in Ihrem HTML:

<tr *ngFor="let obj of objects | orderBy : ObjFieldName: OrderByType">

ObjFieldName: Objektfeldname, den Sie sortieren möchten;

OrderByType: boolean; wahr: absteigende Reihenfolge; falsch: aufsteigend;

GuoJunjun
quelle
Für Zeichenfolgenargumente, die a [orderField] - b [orderField] vergleichen, wird NaN
Piotr Pęczek
Für Datumsargumente funktioniert es nicht. Das Datumsformat als Text wird falsch sortiert.
Rafael Pizao
9

Angular wird nicht sofort mit einem orderBy-Filter geliefert, aber wenn wir uns für einen entscheiden, können wir problemlos einen erstellen. Es gibt jedoch einige Einschränkungen, die wir beachten müssen, um Geschwindigkeit und Minimierung zu erreichen. Siehe unten.

Eine einfache Pfeife würde ungefähr so ​​aussehen.

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

@Pipe({
  name: 'sort'
})
export class SortPipe implements PipeTransform {
  transform(ary: any, fn: Function = (a,b) => a > b ? 1 : -1): any {
    return ary.sort(fn)
  }
}

Diese Pipe akzeptiert eine Sortierfunktion ( fn) und gibt ihr einen Standardwert, mit dem ein Array von Grundelementen auf sinnvolle Weise sortiert wird. Wir haben die Möglichkeit, diese Sortierfunktion zu überschreiben, wenn wir dies wünschen.

Ein Attributname wird nicht als Zeichenfolge akzeptiert, da Attributnamen einer Minimierung unterliegen. Sie ändern sich, wenn wir unseren Code minimieren, aber Minifizierer sind nicht intelligent genug, um auch den Wert in der Vorlagenzeichenfolge zu minimieren.

Sortieren von Grundelementen (Zahlen und Zeichenfolgen)

Wir könnten dies verwenden, um ein Array von Zahlen oder Zeichenfolgen mit dem Standardkomparator zu sortieren:

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

@Component({
  selector: 'cat',
  template: `
    {{numbers | sort}}
    {{strings | sort}}
  `
})
export class CatComponent
  numbers:Array<number> = [1,7,5,6]
  stringsArray<string> = ['cats', 'hats', 'caveats']
}

Sortieren eines Arrays von Objekten

Wenn wir ein Array von Objekten sortieren möchten, können wir ihm eine Komparatorfunktion geben.

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

@Component({
  selector: 'cat',
  template: `
    {{cats | sort:byName}}
  `
})
export class CatComponent
  cats:Array<Cat> = [
    {name: "Missy"},
    {name: "Squoodles"},
    {name: "Madame Pompadomme"}
  ]
  byName(a,b) {
    return a.name > b.name ? 1 : -1
  }
}

Vorsichtsmaßnahmen - reine oder unreine Rohre

Angular 2 hat ein Konzept von reinen und unreinen Rohren.

Eine reine Pipe optimiert die Änderungserkennung anhand der Objektidentität. Dies bedeutet, dass die Pipe nur ausgeführt wird, wenn das Eingabeobjekt seine Identität ändert, z. B. wenn wir dem Array ein neues Element hinzufügen. Es wird nicht in Objekte absteigen. Dies bedeutet, dass wenn wir ein verschachteltes Attribut ändern: this.cats[2].name = "Fluffy"Beispielsweise wird die Pipe nicht erneut ausgeführt. Dies hilft Angular, schnell zu sein. Winkelrohre sind standardmäßig rein.

Ein unreines Rohr hingegen überprüft Objektattribute. Dies macht es möglicherweise viel langsamer. Da nicht garantiert werden kann, was die Rohrleitungsfunktion tut (z. B. je nach Tageszeit unterschiedlich sortiert), wird jedes Mal, wenn ein asynchrones Ereignis auftritt , eine unreine Rohrleitung ausgeführt. Dies verlangsamt Ihre App erheblich, wenn das Array groß ist.

Das Rohr oben ist rein. Dies bedeutet, dass es nur ausgeführt wird, wenn die Objekte im Array unveränderlich sind. Wenn Sie eine Katze wechseln, müssen Sie das gesamte Katzenobjekt durch ein neues ersetzen.

this.cats[2] = {name:"Tomy"}

Wir können das Obige in ein unreines Rohr ändern, indem wir das reine Attribut festlegen:

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

@Pipe({
  name: 'sort',
  pure: false
})
export class SortPipe implements PipeTransform {
  transform(ary: any, fn: Function = (a,b) => a > b ? 1 : -1): any {
    return ary.sort(fn)
  }
}

Diese Pipe steigt in Objekte ab, ist jedoch langsamer. Mit Vorsicht verwenden.

überleuchtet
quelle
Danke .. Hat mir sehr geholfen. Aber eine Frage. Wenn wir zum Sortieren keine Pipe oder Filter verwenden sollten, was ist der beste Ansatz? Ich habe überall gesucht, jeder gibt eine Lösung, indem er eine Pfeife erstellt.
Pavan Shukla
@PavanShukla Sie können eine Pipe verwenden. Stellen Sie einfach sicher, dass Ihre Array-Einträge unveränderlich sind, und erstellen Sie eine reine Pipe. Wenn Sie kein großes Array haben, erstellen Sie eine unreine Pipe und sortieren Sie jeden Render. Alternativ können Sie ein sortiertes Array als Attribut Ihrer Komponente erstellen und dieses rendern.
Superluminary
Ich habe die array.sort-Logik beim Klicken auf jede Spaltenüberschrift verwendet. Ich mache diesen Vorgang auf dem Display-Daten-Array. Ist das ein guter Weg?
Pavan Shukla
7

Ich habe eine OrderBy-Pipe erstellt, die genau das tut, was Sie brauchen. Es unterstützt auch das Sortieren nach mehreren Spalten einer Aufzählung von Objekten.

<li *ngFor="#todo in todos | orderBy : ['completed']">{{todo.name}} {{todo.completed}}</li>

Diese Pipe ermöglicht das Hinzufügen weiterer Elemente zum Array nach dem Rendern der Seite und sortiert das Array mit den Aktualisierungen dynamisch.

Ich habe hier einen Bericht über den Prozess .

Und hier ist eine funktionierende Demo: http://fuelinteractive.github.io/fuel-ui/#/pipe/orderby und https://plnkr.co/edit/DHLVc0?p=info

Cory Shaw
quelle
Sie behandeln keine Nullwerte.
Ali Habibzadeh
if (a == null) a = 0; wenn (b == null) b = 0;
Ali Habibzadeh
Auch Werte mit gleichem Wert sind nervös und bewegen sich, wenn Sie in der Benutzeroberfläche
herumklicken
@XGreen danke dafür. Ich werde in der nächsten Aktualisierung der Kraftstoff-Benutzeroberfläche Unterstützung für null / undefinierte Werte hinzufügen. Was die Sprungkraft gleicher Werte betrifft, sehe ich das nicht. Welchen Browser verwenden Sie?
Cory Shaw
Chrome Version 50.0.2661.86 (64-Bit), OSX El Capitan
Ali Habibzadeh
4

Empfehlen Sie, dass Sie lodash mit eckigen verwenden, dann wird Ihre Pfeife als nächstes sein:

import {Pipe, PipeTransform} from '@angular/core';
import * as _ from 'lodash'
@Pipe({
    name: 'orderBy'
})
export class OrderByPipe implements PipeTransform {

    transform(array: Array<any>, args?: any): any {
        return _.sortBy(array, [args]);
    }

}

und benutze es in HTML wie

*ngFor = "#todo of todos | orderBy:'completed'"

und vergessen Sie nicht, Pipe zu Ihrem Modul hinzuzufügen

@NgModule({
    ...,
    declarations: [OrderByPipe, ...],
    ...
})
Александр Петрик
quelle
Ich mag Ihren Ansatz Александр Петрик, aber ich bevorzuge es, ein Array auf Vorlage zu senden: orderBy: ['field1', 'field2'] Und dann die Pipe aufzurufen: return _.sortBy (array, args);
Eric
1
Das Problem bei der Verwendung von _.sortBy besteht darin, dass Sie keine absteigende Reihenfolge angeben können. Ich habe festgestellt, dass Sie mit _.orderBy für jedes Feld eine benutzerdefinierte Reihenfolge angeben können. dh: _.orderBy (Array, ['field1', 'field2'], ['asc', 'desc'])
Eric
3

Dies funktioniert für jedes Feld, das Sie übergeben. ( WICHTIG: Es wird nur alphabetisch sortiert. Wenn Sie also ein Datum übergeben, wird es als Alphabet und nicht als Datum sortiert.)

/*
 *      Example use
 *      Basic Array of single type: *ngFor="let todo of todoService.todos | orderBy : '-'"
 *      Multidimensional Array Sort on single column: *ngFor="let todo of todoService.todos | orderBy : ['-status']"
 *      Multidimensional Array Sort on multiple columns: *ngFor="let todo of todoService.todos | orderBy : ['status', '-title']"
 */

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

@Pipe({name: "orderBy", pure: false})
export class OrderByPipe implements PipeTransform {

    value: string[] = [];

    static _orderByComparator(a: any, b: any): number {

        if (a === null || typeof a === "undefined") { a = 0; }
        if (b === null || typeof b === "undefined") { b = 0; }

        if (
            (isNaN(parseFloat(a)) ||
            !isFinite(a)) ||
            (isNaN(parseFloat(b)) || !isFinite(b))
        ) {
            // Isn"t a number so lowercase the string to properly compare
            a = a.toString();
            b = b.toString();
            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
    }

    public transform(input: any, config = "+"): any {
        if (!input) { return input; }

        // make a copy of the input"s reference
        this.value = [...input];
        let value = this.value;
        if (!Array.isArray(value)) { return value; }

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

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

                return value.sort(function(a: any, b: any) {
                    let aValue = a[property];
                    let bValue = b[property];

                    let propertySplit = property.split(".");

                    if (typeof aValue === "undefined" && typeof bValue === "undefined" && propertySplit.length > 1) {
                        aValue = a;
                        bValue = b;
                        for (let j = 0; j < propertySplit.length; j++) {
                            aValue = aValue[propertySplit[j]];
                            bValue = bValue[propertySplit[j]];
                        }
                    }

                    return !desc
                        ? OrderByPipe._orderByComparator(aValue, bValue)
                        : -OrderByPipe._orderByComparator(aValue, bValue);
                });
            }
        } else {
            // Loop over property of the array in order and sort
            return value.sort(function(a: any, b: any) {
                for (let i = 0; i < config.length; i++) {
                    let desc = config[i].substr(0, 1) === "-";
                    let property = config[i].substr(0, 1) === "+" || config[i].substr(0, 1) === "-"
                        ? config[i].substr(1)
                        : config[i];

                    let aValue = a[property];
                    let bValue = b[property];

                    let propertySplit = property.split(".");

                    if (typeof aValue === "undefined" && typeof bValue === "undefined" && propertySplit.length > 1) {
                        aValue = a;
                        bValue = b;
                        for (let j = 0; j < propertySplit.length; j++) {
                            aValue = aValue[propertySplit[j]];
                            bValue = bValue[propertySplit[j]];
                        }
                    }

                    let comparison = !desc
                        ? OrderByPipe._orderByComparator(aValue, bValue)
                        : -OrderByPipe._orderByComparator(aValue, bValue);

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

                return 0; // equal each other
            });
        }
    }
}
CommonSenseCode
quelle
Können Sie ein Verwendungsbeispiel veröffentlichen?
TheUnreal
Ich kann den von Ihnen angegebenen Code nicht kompilieren. Ich erhalte die Fehlermeldung, dass @Componentkeine pipesEigenschaft vorhanden ist.
Azimuth
3

Dies ist ein guter Ersatz für AngularJs Orderby- Rohr in Winkel 4 . Einfach und leicht zu bedienen.

Dies ist die Github-URL für weitere Informationen unter https://github.com/VadimDez/ngx-order-pipe

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

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

  transform(value: any | any[], expression?: any, reverse?: boolean): any {
    if (!value) {
      return value;
    }

    const isArray = value instanceof Array;

    if (isArray) {
      return this.sortArray(value, expression, reverse);
    }

    if (typeof value === 'object') {
      return this.transformObject(value, expression, reverse);
    }

    return value;
  }

  /**
   * Sort array
   *
   * @param value
   * @param expression
   * @param reverse
   * @returns {any[]}
   */
  private sortArray(value: any[], expression?: any, reverse?: boolean): any[] {
    const isDeepLink = expression && expression.indexOf('.') !== -1;

    if (isDeepLink) {
      expression = OrderPipe.parseExpression(expression);
    }

    let array: any[] = value.sort((a: any, b: any): number => {
      if (!expression) {
        return a > b ? 1 : -1;
      }

      if (!isDeepLink) {
        return a[expression] > b[expression] ? 1 : -1;
      }

      return OrderPipe.getValue(a, expression) > OrderPipe.getValue(b, expression) ? 1 : -1;
    });

    if (reverse) {
      return array.reverse();
    }

    return array;
  }


  /**
   * Transform Object
   *
   * @param value
   * @param expression
   * @param reverse
   * @returns {any[]}
   */
  private transformObject(value: any | any[], expression?: any, reverse?: boolean): any {
    let parsedExpression = OrderPipe.parseExpression(expression);
    let lastPredicate = parsedExpression.pop();
    let oldValue = OrderPipe.getValue(value, parsedExpression);

    if (!(oldValue instanceof Array)) {
      parsedExpression.push(lastPredicate);
      lastPredicate = null;
      oldValue = OrderPipe.getValue(value, parsedExpression);
    }

    if (!oldValue) {
      return value;
    }

    const newValue = this.transform(oldValue, lastPredicate, reverse);
    OrderPipe.setValue(value, newValue, parsedExpression);
    return value;
  }

  /**
   * Parse expression, split into items
   * @param expression
   * @returns {string[]}
   */
  private static parseExpression(expression: string): string[] {
    expression = expression.replace(/\[(\w+)\]/g, '.$1');
    expression = expression.replace(/^\./, '');
    return expression.split('.');
  }

  /**
   * Get value by expression
   *
   * @param object
   * @param expression
   * @returns {any}
   */
  private static getValue(object: any, expression: string[]) {
    for (let i = 0, n = expression.length; i < n; ++i) {
      const k = expression[i];
      if (!(k in object)) {
        return;
      }
      object = object[k];
    }

    return object;
  }

  /**
   * Set value by expression
   *
   * @param object
   * @param value
   * @param expression
   */
  private static setValue(object: any, value: any, expression: string[]) {
    let i;
    for (i = 0; i < expression.length - 1; i++) {
      object = object[expression[i]];
    }

    object[expression[i]] = value;
  }
}
Ganesh Kalje
quelle
2

Da wir wissen, dass Filter und Reihenfolge nach aus ANGULAR 2 entfernt sind und wir unsere eigenen schreiben müssen, finden Sie hier ein gutes Beispiel für Plunker und ausführliche Artikel

Es wurde sowohl Filter als auch Orderby verwendet. Hier ist der Code für Order Pipe

import { Pipe, PipeTransform } from '@angular/core';    
@Pipe({  name: 'orderBy' })
export class OrderrByPipe implements PipeTransform {

  transform(records: Array<any>, args?: any): any {       
    return records.sort(function(a, b){
          if(a[args.property] < b[args.property]){
            return -1 * args.direction;
          }
          else if( a[args.property] > b[args.property]){
            return 1 * args.direction;
          }
          else{
            return 0;
          }
        });
    };
 }
Ali Adravi
quelle
2

Sie können dies für Objekte verwenden:

@Pipe({
  name: 'sort',
})
export class SortPipe implements PipeTransform {

  transform(array: any[], field: string): any[] {
    return array.sort((a, b) => a[field].toLowerCase() !== b[field].toLowerCase() ? a[field].toLowerCase() < b[field].toLowerCase() ? -1 : 1 : 0);
  }

}
Andre Coetzee
quelle
2

Fügen Sie in package.json Folgendes hinzu: (Diese Version ist für Angular 2 in Ordnung):

  "ngx-order-pipe": "^1.1.3",

In Ihrem Typoskript-Modul (und importiert das Array):

  import { OrderModule } from 'ngx-order-pipe';
VincentPerrin.com
quelle
1
<!-- const cars=['Audi','Merc','BMW','Volvo','Tesla'] -->

<ul>
  <li *ngFor="let car of cars">{{car}}</li>
</ul>


/*
 *ngFor="let c of oneDimArray | sortBy:'asc'"
 *ngFor="let c of arrayOfObjects | sortBy:'asc':'propertyName'"
*/
import { Pipe, PipeTransform } from '@angular/core';
import { orderBy } from 'lodash';

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

  transform(value: any[], order = '', column: string = ''): any[] {
    if (!value || order === '' || !order) { return value; } // no array
    if (!column || column === '') { return sortBy(value); } // sort 1d array
    if (value.length <= 1) { return value; } // array with only one item
    return orderBy(value, [column], [order]);
  }
}
Abdo-Host
quelle
1
Vielen Dank, tolle Antwort
AM - EVS
0

In der aktuellen Version von Angular2 werden orderBy- und ArraySort-Pipes nicht unterstützt. Sie müssen dafür einige benutzerdefinierte Pipes schreiben / verwenden.

Siva
quelle
0

Für die Angular 5+ Version können wir das Paket ngx-order-pipe verwenden

Link zum Quell-Tutorial

Installationspaket

$ npm install ngx-order-pipe --save

In Apps-Modul importieren

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { OrderModule } from 'ngx-order-pipe';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    OrderModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

überall verwenden

  <ul>
    <li *ngFor="let item of (dummyData | orderBy:'name') ">
      {{item.name}}
    </li>
  </ul>
Code Spy
quelle
-1
Component template:
todos| sort: ‘property’:’asc|desc’

Pipe code:

import { Pipe,PipeTransform  } from "angular/core";
import {Todo} from './todo';

@Pipe({
  name: "sort"
})
export class TodosSortPipe implements PipeTransform {
  transform(array: Array<Todo>, args: string): Array<Todo> {
    array.sort((a: any, b: any) => {
      if (a < b) {
        return -1;
      } else if (a > b) {
        return 1;
      } else {`enter code here`
        return 0;
      }
    });
    return array;
  }
}
Sonal Jain
quelle