Angular 2 OrderBy Pipe

Je ne suis pas capable de traduire ce code d’angualr1 en angular2, aucune aide?

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

Voici ce que j’ai fait suite à la réponse de Thierry Templier:

html template:

 *ngFor="#todo of todos | sort" 

fichier de composant:

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

fichier de pipe:

 import { Pipe } from "angular2/core"; import {Todo} from './todo'; @Pipe({ name: "sort" }) export class TodosSortPipe { transform(array: Array, args: ssortingng): Array { array.sort((a: any, b: any) => { if (a  b) { return 1; } else { return 0; } }); return array; } } 

Je suis sûr que l’erreur est dans le @Pipe, im essayant de sortinger un tableau de Todos, ordonné par la propriété todo.completed. Tout d’abord todo.completed = false et que le todo.complete = true.

Je suis honnête, je n’ai pas très bien compris la méthode de transformation et comment passer les arguments dans cette méthode et dans la méthode de sorting.

Comme, quel est l’argument args: ssortingng? a et b, quels sont-ils? d’où ils viennent?

Veuillez consulter https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe pour la discussion complète. Cette citation est la plus pertinente. Fondamentalement, pour les applications de grande envergure qui doivent être minimisées de manière agressive, la logique de filtrage et de sorting doit être déplacée vers le composant lui-même.

“Certains d’entre nous peuvent ne pas vouloir minimiser cela de manière agressive. C’est notre choix. Mais le produit Angular ne doit pas empêcher quelqu’un de mincir de manière agressive. Par conséquent, l’équipe Angular a décidé que

L’équipe Angular et de nombreux développeurs Angular expérimentés vous recommandent vivement de déplacer la logique de filtrage et de sorting dans le composant lui-même. Le composant peut exposer une propriété FiltréHeroes ou sortingésHéros et contrôler le moment et la fréquence d’exécution de la logique de prise en charge. Toutes les fonctionnalités que vous auriez mises dans un canal et partagées dans l’application peuvent être écrites dans un service de filtrage / sorting et injectées dans le composant. ”

Vous pouvez implémenter un canal personnalisé pour cela, qui utilise la méthode de sort des tableaux:

 import { Pipe } from "angular2/core"; @Pipe({ name: "sort" }) export class ArraySortPipe { transform(array: Array, args: ssortingng): Array { array.sort((a: any, b: any) => { if (a < b) { return -1; } else if (a > b) { return 1; } else { return 0; } }); return array; } } 

Et utilisez alors ce tuyau comme décrit ci-dessous. N’oubliez pas de spécifier votre pipe dans l’atsortingbut pipes du composant:

 @Component({ (...) template: ` 
  • (...)
  • `, pipes: [ ArraySortPipe ] }) (...)

    C’est un exemple simple de tableaux avec des valeurs de chaîne, mais vous pouvez avoir un traitement de sorting avancé (basé sur des atsortingbuts d’object dans le cas d’un tableau d’objects, basé sur des parameters de sorting, …).

    Voici un plunkr pour ceci: https://plnkr.co/edit/WbzqDDOqN1oAhvqMkQRQ?p=preview .

    J’espère que ça vous aide, Thierry

    J’ai modifié la réponse de @Thierry Templier pour que le pipe puisse sortinger les objects personnalisés en angular 4:

     import { Pipe, PipeTransform } from "@angular/core"; @Pipe({ name: "sort" }) export class ArraySortPipe implements PipeTransform { transform(array: any[], field: ssortingng): any[] { 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; } } 

    Et pour l’utiliser:

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

    J’espère que cela aide quelqu’un.

    J’ai créé un tube OrderBy qui répond exactement à vos besoins. Il supporte également la possibilité de sortinger sur plusieurs colonnes d’un énumérable d’objects.

     
  • {{todo.name}} {{todo.completed}}
  • Ce tube permet d’append plus d’éléments au tableau après le rendu de la page et de sortinger le tableau avec les mises à jour de manière dynamic.

    J’ai une écriture sur le processus ici .

    Et voici une démo de travail: http://fuelinteractive.github.io/fuel-ui/#/pipe/orderby et https://plnkr.co/edit/DHLVc0?p=info

    Mise à jour de OrderByPipe: correction de chaînes non sortingées.

    créer une classe OrderByPipe:

     import { Pipe, PipeTransform } from "@angular/core"; @Pipe( { name: 'orderBy' } ) export class OrderByPipe implements PipeTransform { transform( array: Array, orderField: ssortingng, orderType: boolean ): Array { 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.toSsortingng().toLowerCase() > be.toSsortingng().toLowerCase() ? -1 : 1) : (be.toSsortingng().toLowerCase() > ae.toSsortingng().toLowerCase() ? -1 : 1); } ); return array; } } 

    dans votre contrôleur:

     @Component({ pipes: [OrderByPipe] }) 

    ou dans votre

      declarations: [OrderByPipe] 

    dans votre HTML:

      

    ObjFieldName: nom du champ d’object que vous souhaitez sortinger;

    OrderByType: booléen; true: ordre décroissant; faux: ascendant;

    Angular ne vient pas avec un filtre orderBy, mais si nous en avons besoin, nous pouvons facilement en créer un. Il y a cependant quelques mises en garde dont nous devons tenir compte en ce qui concerne la rapidité et la minification. Voir ci-dessous.

    Un simple tuyau ressemblerait à ceci.

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

    Ce tube accepte une fonction de sorting ( fn ) et lui atsortingbue une valeur par défaut qui va sortinger un tableau de primitives de manière judicieuse. Nous avons la possibilité de remplacer cette fonction de sorting si nous le souhaitons.

    Il n’accepte pas un nom d’atsortingbut en tant que chaîne, car les noms d’atsortingbut sont sujets à une minification. Ils changeront lorsque nous minifierons notre code, mais les minificateurs ne sont pas assez intelligents pour réduire la valeur de la chaîne de modèle.

    Tri des primitives (nombres et chaînes)

    Nous pourrions l’utiliser pour sortinger un tableau de nombres ou de chaînes à l’aide du comparateur par défaut:

     import { Component } from '@angular/core'; @Component({ selector: 'cat', template: ` {{numbers | sort}} {{ssortingngs | sort}} ` }) export class CatComponent numbers:Array = [1,7,5,6] ssortingngsArray = ['cats', 'hats', 'caveats'] } 

    Trier un tableau d’objects

    Si nous voulons sortinger un tableau d’objects, nous pouvons lui donner une fonction de comparaison.

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

    Mises en garde – tuyaux purs ou impurs

    Angular 2 a un concept de tuyaux purs et impurs.

    Un tuyau pur optimise la détection des changements à l’aide de l’identité de l’object. Cela signifie que le canal ne fonctionnera que si l’object d’entrée change d’identité, par exemple si nous ajoutons un nouvel élément au tableau. Il ne descendra pas dans les objects. Cela signifie que si nous modifions un atsortingbut nested: this.cats[2].name = "Fluffy" par exemple, le tube ne sera pas réexécuté. Cela aide Angular à être rapide. Les tuyaux angulars sont purs par défaut.

    Un tuyau impur, d’autre part, vérifiera les atsortingbuts de l’object. Cela le rend potentiellement beaucoup plus lent. Comme il ne peut pas garantir ce que la fonction pipe va faire (par exemple, il peut être sortingé différemment en fonction de l’heure de la journée), un canal impur s’exécute chaque fois qu’un événement asynchrone se produit. Cela ralentira considérablement votre application si le tableau est volumineux.

    Le tuyau ci-dessus est pur. Cela signifie qu’il ne fonctionnera que lorsque les objects du tableau seront immuables. Si vous changez de chat, vous devez remplacer l’object chat entier par un nouveau.

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

    Nous pouvons changer ce qui précède en un tuyau impur en définissant l’atsortingbut pur:

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

    Ce tuyau descendra dans les objects, mais sera plus lent. Utiliser avec précaution.

    Cela fonctionnera pour n’importe quel domaine que vous lui transmettez. ( IMPORTANT: il ne commandera que par ordre alphabétique, donc si vous passez une date, il le commandera comme alphabet et non comme date)

     /* * 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: ssortingng[] = []; 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"ta number so lowercase the ssortingng to properly compare a = a.toSsortingng(); b = b.toSsortingng(); if (a.toLowerCase() < b.toLowerCase()) { return -1; } if (a.toLowerCase() > b.toLowerCase()) { return 1; } } else { // Parse ssortingngs 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: ssortingng = !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: ssortingng = 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 }); } } } 

    Ceci est un bon remplacement pour les tubes AngularJs de commande angular 4 . Facile et simple à utiliser.

    Ceci est l’URL de github pour plus d’informations 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 {ssortingng[]} */ private static parseExpression(expression: ssortingng): ssortingng[] { 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: ssortingng[]) { 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; } } 

    Recommandez-vous d’utiliser lodash avec angular, alors votre pipe sera la suivante:

     import {Pipe, PipeTransform} from '@angular/core'; import * as _ from 'lodash' @Pipe({ name: 'orderBy' }) export class OrderByPipe implements PipeTransform { transform(array: Array, args?: any): any { return _.sortBy(array, [args]); } } 

    et l’utiliser en HTML comme

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

    et n’oubliez pas d’append Pipe à votre module

     @NgModule({ ..., declarations: [OrderByPipe, ...], ... }) 

    Comme nous soaps que les filtres et les commandes by sont supprimés de ANGULAR 2 et que nous devons écrire les nôtres, voici un bon exemple sur plunker et article détaillé

    Il a utilisé à la fois le filtre et l’ordre, voici le code pour le tube de commande

     import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'orderBy' }) export class OrderrByPipe implements PipeTransform { transform(records: Array, 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; } }); }; } 

    Vous pouvez l’utiliser pour des objects:

     @Pipe({ name: 'sort', }) export class SortPipe implements PipeTransform { transform(array: any[], field: ssortingng): any[] { return array.sort((a, b) => a[field].toLowerCase() !== b[field].toLowerCase() ? a[field].toLowerCase() < b[field].toLowerCase() ? -1 : 1 : 0); } } 

    Dans la version actuelle d’Angular2, les canaux orderBy et ArraySort ne sont pas pris en charge. Vous devez écrire / utiliser des tuyaux personnalisés pour cela.