OrderBy pipe issue

97

No puedo traducir este código de Angualr 1 a Angular 2:

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

Esto es lo que hice siguiendo la respuesta de Thierry Templier:

Plantilla de componente:

*ngFor="#todo of todos | sort"

Código de componente:

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

})

Código de tubería:

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

Estoy tratando de ordenar una matriz de Todos, ordenados por propiedad completed. Primero todo.completed = falsey luego el todo.complete = true.

No entiendo muy bien el transformmétodo y cómo pasar los argumentos en ese método y en el sortmétodo.

Cual es el args: stringargumento? ¿Qué son ay de bdónde vienen?

Alexander Abakumov
fuente
Encontré este paquete de módulos para OrderBy en Angular5 + versiones freakyjolly.com/…
Code Spy

Respuestas:

78

Modifiqué la respuesta de @Thierry Templier para que la tubería pueda ordenar objetos personalizados en angular 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;
  }
}

Y para usarlo:

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

Ojalá esto ayude a alguien.

Sal
fuente
1
Tengo el mensaje: The pipe 'sort' could not be found. ¿Puedo de alguna manera inyectar tubería en mi componente como en 2 tuberías angulares: [ArraySortPipe]?
Matija Župančić
Vea la respuesta de @Thierry Templier sobre cómo inyectar la tubería en el componente de su aplicación
Sal
Debe incluir "ArraySortPipe" en las declaraciones de jerarquía de sus módulos. Algo como: importar {ArraySortPipe} desde './../../shared/filters.pipe'; En 'app.module.ts' y cualquier módulo debajo de él. poner: declaraciones: [ArraySortPipe]
Dudi
71

Consulte https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe para ver la discusión completa. Esta cita es la más relevante. Básicamente, para aplicaciones a gran escala que deben minimizarse de manera agresiva, la lógica de filtrado y clasificación debe trasladarse al componente en sí.

"Es posible que a algunos de nosotros no nos interese minimizar esto de forma agresiva. Esa es nuestra elección. Pero el producto Angular no debería evitar que otra persona lo minimice de forma agresiva. Por lo tanto, el equipo de Angular decidió que todo lo que se envía en Angular se minificará de forma segura.

El equipo de Angular y muchos desarrolladores experimentados de Angular recomiendan encarecidamente que mueva la lógica de filtrado y clasificación al componente en sí. El componente puede exponer una propiedad FilterHeroes o sortedHeroes y tomar el control sobre cuándo y con qué frecuencia ejecutar la lógica de apoyo. Cualquier capacidad que haya puesto en una tubería y compartido en la aplicación puede escribirse en un servicio de filtrado / clasificación e inyectarse en el componente ".

Vitali Kniazeu
fuente
7
¿Cómo debería mover la lógica "al componente en sí" de una manera que pueda "tomar el control sobre cuándo y con qué frecuencia ejecutar la lógica de apoyo"? ¿Hay buenos ejemplos de esto a seguir?
Mzzzzzz
1
@Mzzzzzz Donde se menciona una propiedad como filteredHeroesy sortedHeroes, creo que la idea es que al inicializar el componente ejecutarías alguna lógica de clasificación / filtrado (tal vez llamando a un método desde ngOnInit), luego estableciendo esa propiedad con los resultados ordenados / filtrados, y solo vuelva a ejecutar la lógica / actualice la propiedad si hay algo que desencadena una necesidad (por ejemplo, la interacción del usuario desencadena una llamada AJAX para obtener más héroes, o el usuario hace clic en una casilla de verificación para filtrar la mitad de ellos según algunos criterios, etc.)
jmq
41

Puede implementar una tubería personalizada para esto que aproveche el sortmétodo de matrices:

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

Y luego use esta tubería como se describe a continuación. No olvide especificar su tubería en el pipesatributo del componente:

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

Es una muestra simple para matrices con valores de cadena, pero puede tener algún procesamiento de clasificación avanzado (basado en atributos de objeto en el caso de matriz de objeto, basado en parámetros de clasificación, ...).

Aquí hay un plunkr para esto: https://plnkr.co/edit/WbzqDDOqN1oAhvqMkQRQ?p=preview .

Espero que te ayude, Thierry

Thierry Templier
fuente
1
Gracias por su respuesta, ¿puede explicar el método de clasificación?
1
De hecho, el sortmétodo es un método del Arrayobjeto JavaScript . Vea este enlace: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .
Thierry Templier
Ok, lo tengo, usa el método de clasificación de JavaScript con una función de comparación como argumento. ¡gracias!
1
Desafortunadamente, el plunker está en desuso. Thierry?
4
la pipes: [..]declaración ya no es válida (y ya no es necesaria)
phil294
9

OrderByPipe actualizado: se corrigieron las cadenas sin clasificar.

crear una clase 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;
  }
}

en tu controlador:

@Component({
pipes: [OrderByPipe]
})

o en tu

 declarations: [OrderByPipe]

en tu html:

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

ObjFieldName: nombre del campo del objeto que desea ordenar;

OrderByType: boolean; verdadero: orden descendente; falso: ascendente;

GuoJunjun
fuente
Para argumentos de cadena comparando a [orderField] - b [orderField] devuelve NaN
Piotr Pęczek
Para los argumentos de fecha, no funciona. El formato de fecha como texto se ordenará incorrectamente.
Rafael Pizao
9

Angular no viene con un filtro orderBy listo para usar, pero si decidimos que necesitamos uno, podemos crear uno fácilmente. Sin embargo, hay algunas advertencias que debemos tener en cuenta en relación con la velocidad y la minificación. Vea abajo.

Una pipa simple se vería así.

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

Esta tubería acepta una función de clasificación ( fn) y le da un valor predeterminado que clasificará una matriz de primitivas de una manera sensata. Tenemos la opción de anular esta función de clasificación si lo deseamos.

No acepta un nombre de atributo como una cadena, porque los nombres de atributo están sujetos a minificación. Cambiarán cuando minimicemos nuestro código, pero los minificadores no son lo suficientemente inteligentes como para minimizar también el valor en la cadena de la plantilla.

Ordenar primitivas (números y cadenas)

Podríamos usar esto para ordenar una matriz de números o cadenas usando el comparador predeterminado:

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

Ordenar una matriz de objetos

Si queremos ordenar una matriz de objetos, podemos darle una función de comparación.

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

Advertencias: pipas puras vs impuras

Angular 2 tiene un concepto de tuberías puras e impuras.

Una tubería pura optimiza la detección de cambios utilizando la identidad del objeto. Esto significa que la tubería solo se ejecutará si el objeto de entrada cambia de identidad, por ejemplo, si agregamos un nuevo elemento a la matriz. No descenderá a los objetos. Esto significa que si cambiamos un atributo anidado: this.cats[2].name = "Fluffy"por ejemplo, la tubería no se volverá a ejecutar. Esto ayuda a Angular a ser rápido. Las tuberías angulares son puras por defecto.

Una tubería impura, por otro lado, verificará los atributos del objeto. Esto potencialmente lo hace mucho más lento. Debido a que no puede garantizar lo que hará la función de tubería (tal vez se clasificó de manera diferente según la hora del día, por ejemplo), una tubería impura se ejecutará cada vez que ocurra un evento asincrónico. Esto ralentizará considerablemente su aplicación si la matriz es grande.

La pipa de arriba es pura. Esto significa que solo se ejecutará cuando los objetos de la matriz sean inmutables. Si cambia un gato, debe reemplazar todo el objeto gato por uno nuevo.

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

Podemos cambiar lo anterior a una tubería impura estableciendo el atributo puro:

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

Esta tubería descenderá hacia los objetos, pero será más lenta. Úselo con precaución.

superluminario
fuente
Gracias .. Ayudó mucho. Pero una pregunta ... Si no deberíamos usar tubería o filtro para clasificar, ¿cuál es el mejor enfoque? Busqué por todas partes, todo el mundo está dando una solución creando tubería.
Pavan Shukla
@PavanShukla Puede usar una tubería, solo asegúrese de que las entradas de su matriz sean inmutables y cree una tubería pura. O, si no tiene una matriz grande, haga una tubería impura y ordene cada render. Alternativamente, cree una matriz ordenada como un atributo de su componente y renderícela.
superluminario
He usado la lógica array.sort al hacer clic en cada encabezado de la nube. Estoy haciendo esta operación en la matriz de datos de pantalla ... ¿es una buena manera?
Pavan Shukla
7

He creado una tubería OrderBy que hace exactamente lo que necesita. También admite la posibilidad de ordenar en varias columnas de un enumerable de objetos.

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

Esta tubería permite agregar más elementos a la matriz después de renderizar la página y ordenará la matriz con las actualizaciones de forma dinámica.

Tengo un escrito sobre el proceso aquí .

Y aquí hay una demostración funcional: http://fuelinteractive.github.io/fuel-ui/#/pipe/orderby y https://plnkr.co/edit/DHLVc0?p=info

Cory Shaw
fuente
No está manejando valores nulos.
Ali Habibzadeh
si (a == nulo) a = 0; si (b == nulo) b = 0;
Ali Habibzadeh
También los valores con el mismo valor son saltos y se mueven al hacer clic en la interfaz
Ali Habibzadeh
@XGreen gracias por esto. Agregaré soporte para valores nulos / indefinidos en la próxima actualización de fuel-ui. En cuanto al nerviosismo de valores iguales, no veo esto. ¿Qué navegador estás usando?
Cory Shaw
Versión de Chrome 50.0.2661.86 (64 bits), OSX El Capitan
Ali Habibzadeh
4

Te recomiendo que uses lodash con angular, entonces tu tubería será la siguiente:

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

}

y usarlo en html como

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

y no olvides agregar Pipe a tu módulo

@NgModule({
    ...,
    declarations: [OrderByPipe, ...],
    ...
})
Александр Петрик
fuente
Me gusta su enfoque Александр Петрик pero prefiero enviar una matriz en la plantilla: orderBy: ['field1', 'field2'] Y luego llamar a la tubería: return _.sortBy (array, args);
Eric
1
El problema de usar _.sortBy es que no puede especificar el orden descendiente. Descubrí que usando _.orderBy puedes especificar un orden personalizado para cada campo. es decir: _.orderBy (array, ['field1', 'field2'], ['asc', 'desc'])
Eric
3

Esto funcionará para cualquier campo que le pase. ( IMPORTANTE: Solo se ordenará alfabéticamente, por lo que si pasa una fecha, la ordenará como alfabeto, no como fecha)

/*
 *      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
fuente
¿Puedes publicar un ejemplo de uso?
TheUnreal
No puedo compilar el código que proporcionaste. Me sale un error que dice que @Componentno tiene pipespropiedad.
Azimut
3

Este es un buen reemplazo para AngularJs orderby pipe in angular 4 . Fácil y sencillo de usar.

Esta es la URL de github para obtener más información 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
fuente
2

Como sabemos que el filtro y el orden se eliminan de ANGULAR 2 y necesitamos escribir el nuestro, aquí hay un buen ejemplo sobre plunker y un artículo detallado

Usó tanto el filtro como el orderby, aquí está el código para la tubería de pedido

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
fuente
2

Puede usar esto para objetos:

@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
fuente
2

En package.json, agregue algo como (Esta versión está bien para Angular 2):

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

En su módulo mecanografiado (y matriz de importaciones):

  import { OrderModule } from 'ngx-order-pipe';
VincentPerrin.com
fuente
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
fuente
1
Gracias, excelente respuesta
AM - EVS
0

En la versión actual de Angular2, no se admiten las tuberías orderBy y ArraySort. Necesita escribir / usar algunas tuberías personalizadas para esto.

Siva
fuente
0

Para la versión Angular 5+ podemos usar el paquete ngx-order-pipe

Enlace del tutorial de origen

Paquete de instalación

$ npm install ngx-order-pipe --save

Importar en el módulo de aplicaciones

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

usar en cualquier lugar

  <ul>
    <li *ngFor="let item of (dummyData | orderBy:'name') ">
      {{item.name}}
    </li>
  </ul>
Código espía
fuente
-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
fuente