OrderBy через випуск труби


97

Я не можу перекласти цей код з Angualr 1 на Angular 2:

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

Це те, що я зробив після відповіді Тьєррі Тамплієра:

Шаблон компонента:

*ngFor="#todo of todos | sort"

Код компонента:

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

})

Код труби:

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

Я намагаюся відсортувати масив Todos, упорядкований властивістю completed. Спочатку, todo.completed = falseа потім todo.complete = true.

Я не дуже добре розумію transformметод і те, як передавати аргументи в цьому методі та в sortметоді.

У чому args: stringаргумент? Що aі bі звідки вони беруться?


Я знайшов цей модульний пакет для OrderBy у версіях Angular5
Code Spy

Відповіді:


78

Я змінив відповідь @Thierry Templier, щоб конвеєр міг сортувати власні об'єкти в кутовій 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;
  }
}

І щоб використовувати його:

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

Сподіваємось, це комусь допомагає.


1
Я отримав повідомлення: The pipe 'sort' could not be found. Чи можу я якось ввести трубу в свій компонент, як у кутові 2 труби: [ArraySortPipe]?
Matija Župančić

Дивіться відповідь @Thierry Templier про те, як вводити конвеєр у компонент вашого додатка
Sal

Вам потрібно включити "ArraySortPipe" до оголошень ієрархії модулів. Щось на зразок: імпортувати {ArraySortPipe} з './../../shared/filters.pipe'; У 'app.module.ts' та будь-якому модулі під ним. put: заявки: [ArraySortPipe]
Дуді,

71

Будь ласка, див. Https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe для повного обговорення. Ця цитата є найбільш актуальною. В основному, для великомасштабних програм, які слід агресивно мінімізувати, логіка фільтрації та сортування повинна перейти до самого компонента.

"Деякі з нас можуть не піклуватися про те, щоб зменшити це агресивно. Це наш вибір. Але продукт Angular не повинен перешкоджати комусь іншому агресивно мінімізувати. Тому команда Angular вирішила, що все, що поставляється в Angular, буде безпечно мінімізовано.

Команда Angular та багато досвідчених розробників Angular настійно рекомендують перенести логіку фільтрації та сортування в сам компонент. Компонент може виставляти властивість filteredHeroes або sortedHeroes і контролювати, коли і як часто виконувати підтримуючу логіку. Будь-які можливості, які ви вклали б у конвеєр і поділились у програмі, можна записати в службу фільтрації / сортування та ввести в компонент.


7
Як слід перемістити логіку "у сам компонент" таким чином, щоб "взяти під контроль час і як часто виконувати допоміжну логіку"? Чи є хороші приклади цього для наслідування?
Mzzzzzz

1
@Mzzzzzz Де згадується властивість like filteredHeroesта sortedHeroes, я думаю, ідея полягає в тому, що під час ініціалізації компонента ви запускали б певну логіку сортування / фільтрації (можливо, викликаючи метод з ngOnInit), а потім встановлювали цю властивість з результатами сортування / фільтрування, і повторно запускати логіку / оновлювати властивість, лише якщо щось викликає необхідність (наприклад, взаємодія користувача викликає виклик AJAX, щоб отримати більше героїв, або користувач клацне прапорець, щоб відфільтрувати половину з них на основі деяких критеріїв тощо)
jmq

41

Ви можете реалізувати спеціальну трубу для цього, яка використовує sortметод масивів:

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

І використовуйте тоді цю трубу, як описано нижче. Не забудьте вказати свій канал в pipesатрибуті компонента:

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

Це простий зразок для масивів із рядковими значеннями, але у вас може бути розширена обробка сортування (на основі атрибутів об’єкта у випадку масиву об’єктів, на основі параметрів сортування, ...).

Ось додатковий файл для цього: https://plnkr.co/edit/WbzqDDOqN1oAhvqMkQRQ?p=preview .

Сподіваюся, це допоможе тобі, Тьєррі


1
Дякую за відповідь, чи можете ви пояснити метод сортування?

1
Насправді sortметод є методом Arrayоб'єкта JavaScript . Дивіться це посилання: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .
Тьєррі Темплієр 02

Гаразд, я зрозумів, він використовує метод сортування javascript із функцією порівняння як аргументом. спасибі!

1
На жаль, планка не підтримується. Тьєррі?

4
НЕ pipes: [..]оголошення більше не діє (і більше не треба)
phil294

9

Оновлено OrderByPipe: виправлено не сортування рядків.

створити клас 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;
  }
}

у вашому контролері:

@Component({
pipes: [OrderByPipe]
})

або у вашому

 declarations: [OrderByPipe]

у вашому html:

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

ObjFieldName: ім'я поля об'єкта, яке потрібно відсортувати;

OrderByType: логічний; істина: за спаданням; хибний: за зростанням;


Для рядкових аргументів порівняння [orderField] - b [orderField] повертає NaN
Piotr Pęczek

Для аргументів дати це не працює. Формат дати у вигляді тексту буде неправильно впорядкований.
Рафаель Пізао

9

Angular не постачається із замовленням, відфільтрувавши з коробки, але якщо ми вирішимо, що нам потрібен, ми можемо легко його зробити. Однак є деякі застереження, про які нам слід пам’ятати, пов’язані зі швидкістю та мінімізацією. Дивись нижче.

Проста труба виглядала б приблизно так.

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

Ця труба приймає функцію сортування ( fn) і надає їй значення за замовчуванням, яке розумно відсортує масив примітивів. За бажанням ми маємо можливість замінити цю функцію сортування.

Він не приймає ім'я атрибута як рядок, оскільки імена атрибутів підлягають мініфікації. Вони зміняться, коли ми зменшимо наш код, але мініфайлери недостатньо розумні, щоб також зменшити значення в рядку шаблону.

Сортування примітивів (цифр і рядків)

Ми могли б використовувати це для сортування масиву чисел або рядків, використовуючи порівняльник за замовчуванням:

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

Сортування масиву об’єктів

Якщо ми хочемо відсортувати масив об’єктів, ми можемо надати йому функцію порівняння.

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

Застереження - чисті проти нечистих труб

Angular 2 має концепцію чистої та нечистої труби.

Чистий канал оптимізує виявлення змін за допомогою ідентифікації об’єкта. Це означає, що конвеєр буде працювати, лише якщо вхідний об'єкт змінює ідентичність, наприклад, якщо ми додаємо новий елемент до масиву. Він не буде спускатися на предмети. Це означає, що якщо ми змінимо вкладений атрибут: this.cats[2].name = "Fluffy"наприклад, конвеєр не повториться. Це допомагає Angular бути швидким. Кутові труби за замовчуванням чисті.

Натомість нечиста труба перевірятиме атрибути об’єкта. Це потенційно робить його набагато повільнішим. Оскільки він не може гарантувати, що буде виконувати функція конвеєра (можливо, він сортується по-різному, залежно від часу доби), нечистий конвеєр буде запускатися кожного разу, коли відбувається асинхронна подія. Це значно уповільнить вашу програму, якщо масив великий.

Труба вгорі чиста. Це означає, що він буде працювати лише тоді, коли об'єкти в масиві незмінні. Якщо ви міняєте кота, ви повинні замінити весь котячий об’єкт новим.

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

Ми можемо змінити вищезазначене на нечисту трубу, встановивши атрибут pure:

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

Ця труба опуститься в об'єкти, але буде повільнішою. Використовуйте обережно.


Дякую .. Допоміг дуже. Але одне питання .. Якщо нам не слід використовувати трубу чи фільтр для сортування, який найкращий підхід? Я шукав скрізь, всі дають рішення, створюючи трубу.
Паван Шукла,

@PavanShukla Ви можете використовувати конвеєр, просто переконайтесь, що ваші записи масиву незмінні та створіть чистий конвеєр. Або, якщо у вас немає великого масиву, зробіть нечисту трубу та відсортуйте кожен візуалізатор. З іншого боку, створіть відсортований масив як атрибут вашого компонента і зробіть це.
надсвітлий

Я використовував логіку array.sort при клацанні кожного заголовка cloumn. Я роблю цю операцію з відображенням масиву даних .. це хороший спосіб?
Паван Шукла,

7

Я створив трубу OrderBy, яка робить саме те, що вам потрібно. Він підтримує можливість сортування за кількома стовпцями з безлічі об'єктів.

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

Цей конвеєр дозволяє додавати більше елементів до масиву після рендеринга сторінки та динамічно сортуватиме масив із оновленнями.

У мене є запис про процес тут .

І ось робоча демонстрація: http://fuelinteractive.github.io/fuel-ui/#/pipe/orderby та https://plnkr.co/edit/DHLVc0?p=info


Ви не обробляєте нульові значення.
Алі Хабібзаде

якщо (a == нуль) a = 0; якщо (b == нуль) b = 0;
Алі Хабібзаде

Також значення з однаковим значенням є стрибкоподібними і рухаються, коли ви клацаєте по інтерфейсу
Алі Хабібзаде

@XGreen дякую за це. Я додаю підтримку нульових / невизначених значень у наступному оновленні пального-ui. Що стосується стрибковості рівних значень, я цього не бачу. Який браузер ви використовуєте?
Кори Шоу

Версія Chrome 50.0.2661.86 (64-розрядна), OSX El Capitan
Алі Хабібзаде

4

Рекомендуйте використовувати lodash з angular, тоді ваша труба буде наступною:

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

}

і використовувати його в html, як

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

і не забудьте додати Pipe до свого модуля

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

Мені подобається ваш підхід Александр Петрик, але я віддаю перевагу надсилати масив за шаблоном: orderBy: ['field1', 'field2'] А потім зателефонувати до каналу: return _.sortBy (array, args);
Ерік,

1
Проблема використання _.sortBy полягає в тому, що ви не можете вказати порядок спадання. Я виявив, що за допомогою _.orderBy ви можете вказати власний порядок для кожного поля. тобто: _.orderBy (масив, ['field1', 'field2'], ['asc', 'desc'])
Ерік

3

Це буде працювати для будь-якого поля, яке ви перейдете до нього. ( ВАЖЛИВО: Це буде замовити тільки в алфавітному порядку , так що якщо ви передаєте дату накаже як алфавіт не як дата)

/*
 *      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
            });
        }
    }
}

Чи можете ви опублікувати приклад використання?
TheUnreal

Я не можу скомпілювати код, який ви надали. Я отримую повідомлення про помилку із заявою, що @Componentне має pipesвластивості.
Азімут,

3

Це хороша заміна для AngularJs OrderBy труби в кутових 4 . Легкий і простий у використанні.

Це URL-адреса github для отримання додаткової інформації 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;
  }
}

2

Оскільки ми знаємо, що фільтр та порядок за видалені з ANGULAR 2, і нам потрібно написати власні, ось хороший приклад про plunker та детальна стаття

Він використовував як фільтр, так і orderby, ось код для каналу замовлення

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

2

Ви можете використовувати це для об'єктів:

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

}

2

У package.json додайте щось на зразок (Ця версія добре для Angular 2):

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

У вашому модулі машинопису (і імпортує масив):

  import { OrderModule } from 'ngx-order-pipe';

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

1
Дякую, чудова відповідь
AM - EVS

0

У поточній версії Angular2 канали orderBy та ArraySort не підтримуються. Для цього вам потрібно написати / використати кілька спеціальних каналів.


0

Для версії Angular 5+ ми можемо використовувати пакет ngx-order-pipe

Посилання на підручник з джерела

Встановити пакет

$ npm install ngx-order-pipe --save

Імпортувати в модуль додатків

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

використовувати де завгодно

  <ul>
    <li *ngFor="let item of (dummyData | orderBy:'name') ">
      {{item.name}}
    </li>
  </ul>


-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;
  }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.