Problem z rurą OrderBy

98

Nie jestem w stanie przetłumaczyć tego kodu z Angualr 1 na Angular 2:

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

Oto, co zrobiłem zgodnie z odpowiedzią Thierry Templier:

Szablon komponentu:

*ngFor="#todo of todos | sort"

Kod komponentu:

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

})

Kod rury:

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;
  }
}

Próbuję posortować tablicę Todos uporządkowaną według właściwości completed. Najpierw, todo.completed = falsea potem todo.complete = true.

Nie rozumiem zbyt dobrze transformmetody i sposobu przekazywania argumentów w tej metodzie i sortmetodzie.

Jaki jest args: stringargument? Czym są ai bskąd pochodzą?

Alexander Abakumov
źródło
Znalazłem ten pakiet modułów dla OrderBy w Angular5 + wersje freakyjolly.com/...
Code Spy

Odpowiedzi:

79

Zmodyfikowałem odpowiedź @Thierry Templier, aby rura mogła sortować niestandardowe obiekty w kątowym 4:

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;
  }
}

I aby z niego skorzystać:

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

Mam nadzieję, że to komuś pomoże.

Sal
źródło
1
Mam wiadomość: The pipe 'sort' could not be found. Czy mogę w jakiś sposób wstrzyknąć rurę do mojego komponentu, tak jak w 2 rurach kątowych: [ArraySortPipe]?
Matija Župančić
Zobacz odpowiedź @Thierry Templier, aby dowiedzieć się, jak wstrzyknąć rurkę do komponentu aplikacji
Sal
Musisz uwzględnić „ArraySortPipe” w deklaracjach hierarchii modułów. Coś w rodzaju: import {ArraySortPipe} z „./../../shared/filters.pipe”; W „app.module.ts” i dowolnym module pod nim. put: declarations: [ArraySortPipe]
Dudi
72

Pełną dyskusję można znaleźć pod adresem https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe . Ten cytat jest najbardziej odpowiedni. Zasadniczo w przypadku aplikacji na dużą skalę, które powinny być zminimalizowane agresywnie, logika filtrowania i sortowania powinna zostać przeniesiona do samego składnika.

„Niektórym z nas może nie zależeć na tym agresywnym minimalizowaniu. To nasz wybór. Ale produkt Angular nie powinien przeszkadzać komuś innemu przed agresywną minifikacją. Dlatego zespół Angular zdecydował, że wszystko, co jest dostarczane w Angular, zostanie zminimalizowane bezpiecznie.

Zespół Angular i wielu doświadczonych programistów Angular zdecydowanie zaleca przeniesienie logiki filtrowania i sortowania do samego komponentu. Składnik może uwidaczniać właściwość filterHeroes lub sortHeroes i przejmować kontrolę nad tym, kiedy i jak często ma wykonywać logikę pomocniczą. Wszelkie możliwości, które zostałyby umieszczone w potoku i udostępnione w całej aplikacji, można zapisać w usłudze filtrowania / sortowania i wstrzyknąć do komponentu ”.

Vitali Kniazeu
źródło
7
Jak przenieść logikę „do samego komponentu” w sposób, który może „przejąć kontrolę nad tym, kiedy i jak często wykonywać logikę pomocniczą”? Czy istnieją dobre przykłady do naśladowania?
Mzzzzzz
1
@Mzzzzzz Tam, gdzie wspomina się o właściwości takiej jak filteredHeroesi sortedHeroes, myślę, że chodzi o to, że podczas inicjowania komponentu uruchomisz logikę sortowania / filtrowania (być może wywołując metodę z ngOnInit), a następnie ustawiając tę ​​właściwość z posortowanymi / przefiltrowanymi wynikami i uruchom ponownie logikę / zaktualizuj właściwość tylko wtedy, gdy jest coś, co wyzwala potrzebę (np. interakcja użytkownika wyzwala wywołanie AJAX, aby uzyskać więcej bohaterów, lub użytkownik klika pole wyboru, aby odfiltrować połowę z nich na podstawie pewnych kryteriów itp.)
jmq
42

Możesz zaimplementować w tym celu niestandardowy potok, który wykorzystuje sortmetodę tablic:

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;
  }
}

A następnie użyj tej rury, jak opisano poniżej. Nie zapomnij podać swojej rury w pipesatrybucie komponentu:

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

Jest to prosty przykład dla tablic z wartościami łańcuchowymi, ale możesz mieć zaawansowane przetwarzanie sortowania (oparte na atrybutach obiektów w przypadku tablicy obiektów, na podstawie parametrów sortowania, ...).

Oto plunkr do tego: https://plnkr.co/edit/WbzqDDOqN1oAhvqMkQRQ?p=preview .

Mam nadzieję, że ci to pomoże, Thierry

Thierry Templier
źródło
1
Dziękuję za odpowiedź, czy możesz wyjaśnić metodę sortowania?
1
W rzeczywistości sortmetoda jest metodą Arrayobiektu JavaScript . Zobacz ten link: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .
Thierry Templier
Ok, rozumiem, używa metody sortowania javascript z funkcją porównania jako argumentem. Dziękuję Ci!
1
Niestety plunker jest przestarzały. Thierry?
4
pipes: [..]deklaracja nieważne (i nie jest to konieczne) jest
phil294
9

Zaktualizowany OrderByPipe: naprawiono brak sortowania ciągów.

utwórz klasę OrderByPipe:

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;
  }
}

w kontrolerze:

@Component({
pipes: [OrderByPipe]
})

lub w twoim

 declarations: [OrderByPipe]

w Twoim html:

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

ObjFieldName: nazwa pola obiektu, które chcesz sortować;

OrderByType: boolean; prawda: malejąco; false: rosnąco;

GuoJunjun
źródło
Dla argumentów typu string porównujących a [orderField] - b [orderField] zwraca NaN
Piotr Pęczek
W przypadku argumentów dat to nie działa. Format daty jako tekst zostanie nieprawidłowo ułożony.
Rafael Pizao
9

Angular nie jest dostarczany z filtrem orderBy po wyjęciu z pudełka, ale jeśli zdecydujemy, że go potrzebujemy, możemy go łatwo zrobić. Są jednak pewne zastrzeżenia, o których musimy wiedzieć, jeśli chodzi o szybkość i minifikację. Zobacz poniżej.

Prosta rura wyglądałaby mniej więcej tak.

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)
  }
}

Ten potok akceptuje funkcję sortowania ( fn) i nadaje jej domyślną wartość, która posortuje tablicę prymitywów w rozsądny sposób. Jeśli chcemy, mamy możliwość nadpisania tej funkcji sortowania.

Nie akceptuje nazwy atrybutu jako łańcucha, ponieważ nazwy atrybutów podlegają minifikacji. Zmienią się, gdy zminimalizujemy nasz kod, ale minifier nie są wystarczająco inteligentne, aby również zminimalizować wartość w ciągu szablonu.

Sortowanie prymitywów (liczb i łańcuchów)

Moglibyśmy użyć tego do posortowania tablicy liczb lub ciągów za pomocą domyślnego komparatora:

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']
}

Sortowanie tablicy obiektów

Jeśli chcemy posortować tablicę obiektów, możemy nadać jej funkcję komparatora.

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
  }
}

Ostrzeżenia - czyste vs. nieczyste rury

Angular 2 ma koncepcję czystych i nieczystych rur.

Czysta rura optymalizuje wykrywanie zmian przy użyciu tożsamości obiektu. Oznacza to, że potok będzie działał tylko wtedy, gdy obiekt wejściowy zmieni tożsamość, na przykład jeśli dodamy nowy element do tablicy. Nie opuści się w przedmioty. Oznacza to, że jeśli zmienimy zagnieżdżony atrybut: this.cats[2].name = "Fluffy"na przykład potok nie zostanie ponownie uruchomiony. To pomaga Angularowi być szybkim. Rury kątowe są domyślnie czyste.

Z drugiej strony nieczysta potok sprawdzi atrybuty obiektu. To potencjalnie sprawia, że ​​jest znacznie wolniejszy. Ponieważ nie może zagwarantować, co zrobi funkcja potoku (być może na przykład posortuje inaczej w zależności od pory dnia), zanieczyszczony potok będzie działał za każdym razem, gdy wystąpi zdarzenie asynchroniczne. Spowoduje to znaczne spowolnienie działania aplikacji, jeśli macierz jest duża.

Rura powyżej jest czysta. Oznacza to, że będzie działać tylko wtedy, gdy obiekty w tablicy są niezmienne. Jeśli zmienisz kota, musisz zastąpić cały obiekt kota nowym.

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

Możemy zmienić powyższe na nieczystą potokę, ustawiając czysty atrybut:

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)
  }
}

Ta rura będzie schodzić w obiekty, ale będzie wolniejsza. Używaj ostrożnie.

superluminium
źródło
Dzięki ... bardzo pomogłem. Ale jedno pytanie… Jeśli nie powinniśmy używać potoku lub filtra do sortowania, jakie jest najlepsze podejście? Szukałem wszędzie, każdy daje rozwiązanie tworząc fajkę.
Pavan Shukla
@PavanShukla Możesz użyć potoku, po prostu upewnij się, że wpisy w tablicy są niezmienne i utwórz czystą potokę. Lub, jeśli nie masz dużej tablicy, utwórz zanieczyszczony potok i posortuj każdy render. Alternatywnie utwórz posortowaną tablicę jako atrybut komponentu i wyrenderuj ją.
superluminium,
Użyłem logiki array.sort po kliknięciu każdego nagłówka cloumn. Robię tę operację na tablicy danych wyświetlacza .. czy to dobry sposób?
Pavan Shukla
7

Stworzyłem rurę OrderBy, która robi dokładnie to, czego potrzebujesz. Obsługuje również możliwość sortowania według wielu kolumn wyliczalnych obiektów.

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

Ten potok pozwala na dodawanie kolejnych elementów do tablicy po wyrenderowaniu strony i dynamicznie sortuje tablicę z aktualizacjami.

Mam tutaj opis tego procesu .

A oto działające demo: http://fuelinteractive.github.io/fuel-ui/#/pipe/orderby i https://plnkr.co/edit/DHLVc0?p=info

Cory Shaw
źródło
Nie obsługujesz wartości null.
Ali Habibzadeh
if (a == null) a = 0; if (b == null) b = 0;
Ali Habibzadeh
Również wartości o tej samej wartości są gwałtowne i poruszają się, gdy klikasz w interfejsie
Ali Habibzadeh
@XGreen dzięki za to. Dodam obsługę wartości null / undefined w następnej aktualizacji paliwa-ui. Jeśli chodzi o skokowość równych wartości, nie widzę tego. Jakiej przeglądarki używasz?
Cory Shaw
Wersja Chrome 50.0.2661.86 (64-bitowa), OSX El Capitan
Ali Habibzadeh
4

Zalecamy użycie lodash z kątownikiem, wtedy twoja rura będzie następna:

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]);
    }

}

i używaj go w formacie HTML

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

i nie zapomnij dodać Pipe do swojego modułu

@NgModule({
    ...,
    declarations: [OrderByPipe, ...],
    ...
})
Александр Петрик
źródło
Podoba mi się twoje podejście Александр Петрик, ale wolę wysyłać tablicę na szablonie: orderBy: ['field1', 'field2'] A potem wywołanie potoku: return _.sortBy (tablica, args);
Eric
1
Problem z używaniem _.sortBy polega na tym, że nie można określić kolejności podrzędnej. Odkryłem, że używając _.orderBy możesz określić niestandardową kolejność dla każdego pola. tj .: _.orderBy (tablica, ['pole1', 'pole2'], ['rosnąco', 'desc'])
Eric
3

To zadziała dla każdego pola, które do niego przekażesz. ( WAŻNE: uporządkuje tylko alfabetycznie, więc jeśli przekażesz datę, uporządkuje ją jako alfabet, a nie jako datę)

/*
 *      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
źródło
Czy możesz opublikować przykład użycia?
TheUnreal
Nie mogę skompilować podanego przez Ciebie kodu. Pojawia się błąd z informacją, że @Componentnie ma pipeswłasności.
Azymut
3

Jest to dobry zamiennik dla rury Orderby AngularJs w kątowej 4 . Łatwy i prosty w użyciu.

To jest adres URL github, aby uzyskać więcej informacji 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
źródło
2

Jak wiemy, filter i order by zostały usunięte z ANGULAR 2 i musimy napisać własne, oto dobry przykład na plunker i szczegółowy artykuł

Używał zarówno filtra, jak i orderby, oto kod dla zamówienia potoku

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
źródło
2

Możesz tego użyć dla obiektów:

@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
źródło
2

W pliku package.json dodaj coś takiego (ta wersja jest odpowiednia dla Angulara 2):

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

W swoim module maszynopisu (i tablicy importów):

  import { OrderModule } from 'ngx-order-pipe';
VincentPerrin.com
źródło
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
źródło
1
Dziękuję, świetna odpowiedź
AM - EVS
0

W aktualnej wersji Angular2 potoki orderBy i ArraySort nie są obsługiwane. Musisz napisać / użyć do tego niestandardowych potoków.

Siva
źródło
0

Dla wersji Angular 5+ możemy użyć pakietu ngx-order-pipe

Link do samouczka źródła

Zainstaluj pakiet

$ npm install ngx-order-pipe --save

Moduł importu w aplikacjach

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 { }

używać wszędzie

  <ul>
    <li *ngFor="let item of (dummyData | orderBy:'name') ">
      {{item.name}}
    </li>
  </ul>
Code Spy
źródło
-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
źródło