[angular] * ngFor에 필터를 적용하는 방법?

분명히 Angular 2는 Angular1에서와 같이 ng-for와 함께 필터 대신 파이프를 사용하여 결과를 필터링합니다. 구현이 여전히 모호한 것처럼 보이지만 명확한 문서는 없습니다.

즉, 내가 달성하려는 것은 다음 관점에서 볼 수 있습니다.

<div *ng-for="#item of itemsList" *ng-if="conditon(item)"></div>

파이프를 사용하여 구현하는 방법은 무엇입니까?



답변

기본적으로 파이프를 작성하여 *ngFor 지시문에 .

컴포넌트에서 :

filterargs = {title: 'hello'};
items = [{title: 'hello world'}, {title: 'hello kitty'}, {title: 'foo bar'}];

템플릿에서 문자열, 숫자 또는 객체를 파이프에 전달하여 필터링 할 수 있습니다.

<li *ngFor="let item of items | myfilter:filterargs">

파이프에서 :

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

@Pipe({
    name: 'myfilter',
    pure: false
})
export class MyFilterPipe implements PipeTransform {
    transform(items: any[], filter: Object): any {
        if (!items || !filter) {
            return items;
        }
        // filter items array, items which match and return true will be
        // kept, false will be filtered out
        return items.filter(item => item.title.indexOf(filter.title) !== -1);
    }
}

파이프를 등록하십시오 app.module.ts; 더 이상 파이프를 등록 할 필요가 없습니다.@Component

import { MyFilterPipe } from './shared/pipes/my-filter.pipe';

@NgModule({
    imports: [
        ..
    ],
    declarations: [
        MyFilterPipe,
    ],
    providers: [
        ..
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

플 런커입니다 결과를 제한하기 위해 사용자 지정 필터 파이프와 내장 슬라이스 파이프의 사용을 시연 입니다.

제발 노트 (여러 주석이 지적한대로)하는 이유가 없음이 내장 된 이유 각도에서 필터 파이프.


답변

많은 사람들이 훌륭한 접근 방식을 가지고 있지만 여기서 목표는 일반적이고 * ngFor와 관련하여 모든 경우에서 매우 재사용 가능한 배열 파이프를 정의하는 것입니다.

callback.pipe.ts (모듈의 선언 배열에 이것을 추가하는 것을 잊지 마십시오)

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

@Pipe({
    name: 'callback',
    pure: false
})
export class CallbackPipe implements PipeTransform {
    transform(items: any[], callback: (item: any) => boolean): any {
        if (!items || !callback) {
            return items;
        }
        return items.filter(item => callback(item));
    }
}

그런 다음 구성 요소에서 다음과 같은 서명 (항목 : any) => boolean 을 사용하여 메소드를 구현해야합니다 . 예를 들어 필자의 경우 18 세 이상인 사용자의 나이를 필터링하는 filterUser라고했습니다.

구성 요소

@Component({
  ....
})
export class UsersComponent {
  filterUser(user: IUser) {
    return !user.age >= 18
  }
}

마지막으로 HTML 코드는 다음과 같습니다.

HTML

<li *ngFor="let user of users | callback: filterUser">{{user.name}}</li>

보시다시피이 파이프는 콜백을 통해 필터링해야하는 항목과 같은 모든 배열에서 상당히 일반적입니다. 제 경우에는 * ngFor like scenarios에 매우 유용하다는 것을 알았습니다.

도움이 되었기를 바랍니다!!!

코드 매트릭스


답변

단순화 된 방법 (성능 문제로 인해 작은 배열에서만 사용됩니다. 큰 배열에서는 코드를 통해 수동으로 필터를 만들어야합니다) :

참조 : https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe

@Pipe({
    name: 'filter'
})
@Injectable()
export class FilterPipe implements PipeTransform {
    transform(items: any[], field : string, value : string): any[] {
      if (!items) return [];
      if (!value || value.length == 0) return items;
      return items.filter(it =>
      it[field].toLowerCase().indexOf(value.toLowerCase()) !=-1);
    }
}

용법:

<li *ngFor="let it of its | filter : 'name' : 'value or variable'">{{it}}</li>

변수를 두 번째 인수로 사용하는 경우 따옴표를 사용하지 마십시오.


답변

이것이 파이프를 사용하지 않고 구현 한 것입니다.

component.html

<div *ngFor="let item of filter(itemsList)">

component.ts

@Component({
....
})
export class YourComponent {
  filter(itemList: yourItemType[]): yourItemType[] {
    let result: yourItemType[] = [];
    //your filter logic here
    ...
    ...
    return result;
  }
}


답변

언제 들어 왔는지 확실하지 않지만 이미 그렇게 할 수있는 슬라이스 파이프를 만들었습니다. 잘 문서화되어 있습니다.

https://angular.io/docs/ts/latest/api/common/index/SlicePipe-pipe.html

<p *ngFor="let feature of content?.keyFeatures | slice:1:5">
   {{ feature.description }}
</p>


답변

다음을 사용할 수도 있습니다.

<template ngFor let-item [ngForOf]="itemsList">
    <div *ng-if="conditon(item)"></div>
</template>

아이템이 조건과 일치하는 경우에만 div를 표시합니다

자세한 내용은 각도 설명서 를 참조하십시오. 인덱스가 필요한 경우 다음을 사용하십시오.

<template ngFor let-item [ngForOf]="itemsList" let-i="index">
    <div *ng-if="conditon(item, i)"></div>
</template>


답변

Angular2의 파이프는 명령 행의 파이프와 유사합니다. 각 선행 값의 출력은 파이프 다음에 필터에 공급되어 다음과 같이 필터를 쉽게 연결할 수 있습니다.

<template *ngFor="#item of itemsList">
    <div *ngIf="conditon(item)">{item | filter1 | filter2}</div>
</template>