programing

파이프별 주문 발행

lastcode 2023. 9. 4. 20:08
반응형

파이프별 주문 발행

이 코드를 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;
  }
}

나는여가분합니다고려류하지의 을 정리하려고 합니다.Todo된 부산에의해주문된동된▁s문주▁by해의▁s.completed .todo.completed = false 그음에다.todo.complete = true.

나는 잘 이해하지 못합니다.transform 및 합니다.sort방법.

무입니까는 입니까?args: string논쟁?무엇이a그리고.b그리고 그들은 어디에서 왔습니까?

파이프가 사용자 지정 객체를 각도 4로 정렬할 수 있도록 @Tier Templier의 응답을 수정했습니다.

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'"

이것이 누군가에게 도움이 되기를 바랍니다.

자세한 내용은 https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe 을 참조하십시오.이 인용문은 가장 관련성이 있습니다.기본적으로 적극적으로 최소화해야 하는 대규모 앱의 경우 필터링 및 정렬 로직이 구성 요소 자체로 이동해야 합니다.

"우리 중 일부는 이것을 공격적으로 축소하는 것을 꺼릴 수 있습니다.그건 우리의 선택입니다.그러나 Angular 제품은 다른 사람이 공격적으로 채굴하는 것을 막아서는 안 됩니다.따라서 Angular 팀은 Angular에 선적된 모든 것이 안전하게 최소화될 것이라고 결정했습니다.

Angular 팀과 많은 경험이 많은 Angular 개발자들은 필터링 및 정렬 로직을 구성요소 자체로 이동할 것을 강력히 권장합니다.이 구성 요소는 필터링된 데이터를 노출할 수 있습니다.영웅 또는 정렬됨Heroes는 지원 논리를 언제, 얼마나 자주 실행해야 하는지를 소유하고 제어합니다.파이프에 넣고 앱 전체에서 공유했을 모든 기능을 필터링/정렬 서비스로 작성하여 구성 요소에 주입할 수 있습니다."

를 위사정파를구현수있다습니할이프의용해자▁▁for▁leverages를 활용하는 사용자 정의 할 수 .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 .

도움이 되길 바래, 티에리

업데이트된 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: 부울, true: 내림차순, false: 오름차순,

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

함수 function)를 허용합니다.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는 순수하고 불순한 파이프의 개념을 가지고 있습니다.

순수 파이프는 객체 ID를 사용하여 변경 감지를 최적화합니다.즉, 입력 개체가 ID를 변경하는 경우(예: 배열에 새 항목을 추가하는 경우)에만 파이프가 실행됩니다.물체로 하강하지 않습니다.즉, 중첩된 속성을 변경하면 다음과 같습니다.this.cats[2].name = "Fluffy"예를 들어 파이프가 다시 실행되지 않습니다.이렇게 하면 Angular가 빨라집니다.각 파이프는 기본적으로 순수합니다.

반면에 불순한 파이프는 객체 속성을 확인합니다.이로 인해 속도가 훨씬 느려질 수 있습니다.파이프 함수가 수행할 작업을 보장할 수 없기 때문에(예를 들어 시간에 따라 다르게 정렬되었을 수 있음), 비동기 이벤트가 발생할 때마다 불순한 파이프가 실행됩니다.배열이 크면 앱 속도가 상당히 느려집니다.

위의 파이프는 순수합니다.즉, 배열의 개체가 불변인 경우에만 실행됩니다.고양이를 변경할 경우 전체 고양이 개체를 새 개체로 바꿔야 합니다.

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

순수 속성을 설정하여 위의 파이프를 불순물 파이프로 변경할 수 있습니다.

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

이 파이프는 개체로 하강하지만 속도가 느려집니다.주의하여 사용하십시오.

나는 당신이 필요로 하는 것을 수행하는 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

각도가 있는 로다쉬를 사용할 것을 권장합니다. 그러면 파이프가 다음 단계가 될 것입니다.

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'"

모듈에 파이프를 추가하는 것을 잊지 마십시오.

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

기능은 전달하는 모든 필드에 적용됩니다. (중요: 알파벳 순으로만 정렬되므로 날짜가 지나면 날짜가 아닌 알파벳 순으로 정렬됩니다.)

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

개체에 사용할 수 있습니다.

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

}

이것은 각도 4의 파이프별 AngularJs 주문에 대한 좋은 대체품입니다.사용이 간편하고 간단합니다.

자세한 내용은 github URL을 참조하십시오. 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;
  }
}

우리가 ANGLE 2에서 필터와 주문이 제거되고 우리가 직접 작성해야 한다는 것을 알고 있듯이, 여기 플런커자세한 기사에 대한 좋은 예가 있습니다.

필터와 주문 기준을 모두 사용했습니다. 주문 파이프 코드는 다음과 같습니다.

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

포장되어 있습니다.json, 다음과 같은 것을 추가합니다(이 버전은 Angular 2에 대해서는 괜찮습니다).

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

유형 스크립트 모듈(및 배열 가져오기)에서 다음을 수행합니다.

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

Angular 5+ Version의 경우 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>

Angular2의 현재 버전에서는 orderBy 및 ArraySort 파이프가 지원되지 않습니다.이를 위해 몇 가지 사용자 지정 파이프를 작성/사용해야 합니다.

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

Angular JS의 파이프별 주문은 지원하지만 Angular(상위 버전)는 지원하지 않습니다. 성능 속도를 높이기 위해 논의된 세부 정보를 찾아보십시오.

https://angular.io/guide/styleguide#do-not-add-filtering-and-sorting-logic-to-pipes

Vitali의 응답에 추가하여, 이전 문서는 다음과 같습니다./pipes#appendix-no-filterpipe-or-orderbypipe어떤 이유로 인해 더 이상 사용할 수 없습니다. 문제는 https://github.com/angular/angular/issues/41652 에서 논의되고 있습니다.

@Sal의 답변은 다음과 같습니다.

  • 더 나은 TypeScript 타이핑
  • 배열 )sortKey)
  • input않음 ㅠㅠㅠㅠㅠㅠㅠㅠㅠ

참고: 또제습니다했거한도 했습니다.Array.isArray() 검사 오류 검사

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

@Pipe({
  name: 'sort'
})
export class SortPipe implements PipeTransform {
  transform<T, K extends keyof T>(input: T[], sortKey?: K): T[] {
    return [...input].sort((a: T, b: T) => {
      const aValue = typeof a === 'object'
        ? a[sortKey]
        : a;
      const bValue = typeof b === 'object'
        ? b[sortKey]
        : b;

      if (aValue < bValue) {
        return -1;
      } else if (aValue > bValue) {
        return 1;
      }

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

언급URL : https://stackoverflow.com/questions/35158817/orderby-pipe-issue

반응형