source

*ngFor에 필터를 적용하는 방법

ittop 2023. 3. 18. 09:22
반응형

*ngFor에 필터를 적용하는 방법

분명히 Angular 2는 ng-for와 함께 Angular1의 필터 대신 파이프를 사용하여 결과를 필터링합니다.다만, 실장은 아직 애매하고 명확한 문서도 없는 것 같습니다.

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

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

커스텀 필터 파이프와 빌트인 슬라이스 파이프를 사용하여 결과를 제한하는 방법을 시연하는 Plunker가 있습니다.

(여러 해설자가 지적한 바와 같이) Angular에 내장 필터 파이프가 없는 데는 이유가 있습니다.

많은 분들이 훌륭한 접근방식을 가지고 계시지만, 여기서의 목표는 범용적이고 *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) => 부울을 가진 메서드를 구현해야 합니다.예를 들어, 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 같은 시나리오에 매우 유용하다는 것을 알았습니다.

도움이 되었으면 좋겠어!!!

코드 매트릭스

심플한 방법(퍼포먼스 문제로 인해 소규모 어레이에서만 사용).대규모 어레이에서는, 코드를 사용해 수동으로 필터를 작성할 필요가 있습니다).

참조: 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.displaces(컴포넌트).

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

컴포넌트.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>

Angular 6과 함께 ngFor를 필터링하는 간단한 솔루션입니다.다음은 예를 제시하겠습니다.

<span *ngFor="item of itemsList"  >
  <div *ngIf="yourCondition(item)">
    
    your code
    
  </div>
</span>

스팬은 본질적으로 아무것도 나타내지 않기 때문에 유용합니다.

다음 항목도 사용할 수 있습니다.

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

품목이 조건에 일치하는 경우에만 구분 표시가 됩니다.

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

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

오래된 질문인 건 알지만 다른 해결책을 제시하면 도움이 될 것 같아서요.

Angular의 등가이것의 JS

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

Angular 2+에서는 *ngFor 및 *ngIf를 동일한 요소에 사용할 수 없으므로 다음과 같습니다.

<div *ngFor="let item of itemsList">
     <div *ngIf="conditon(item)">
     </div>
</div>

내부 컨테이너로 사용할 수 없는 경우 대신 ng-timeout을 사용하십시오.ng-module은 응용 프로그램에 요소 그룹을 조건부로 추가하고 싶을 때(*ngIf="foo" 사용) 다른 요소로 래핑하지 않을 때 유용합니다.

사용하는 동적 필터 파이프가 있습니다.

소스 데이터:

items = [{foo: 'hello world'}, {foo: 'lorem ipsum'}, {foo: 'foo bar'}];

템플릿에서는 임의의 오브젝트 속성으로 필터를 디나믹하게 설정할 수 있습니다.

<li *ngFor="let item of items | filter:{foo:'bar'}">

파이프:

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

  @Pipe({
    name: 'filter',
  })
  export class FilterPipe implements PipeTransform {
    transform(items: any[], filter: Record<string, any>): any {
      if (!items || !filter) {
        return items;
      }

      const key = Object.keys(filter)[0];
      const value = filter[key];

      return items.filter((e) => e[key].indexOf(value) !== -1);
    }
  }

app.module.ts

파이프가 가장 좋은 방법일 겁니다. 하지만 그 아래도 효과가 있을 겁니다.

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

요건을 위해 저는 범용 컴포넌트를 구현하고 발행합니다.

https://www.npmjs.com/package/w-ng5

이 컴포넌트를 사용하려면 npm과 함께 이 패키지를 설치합니다.

npm install w-ng5 --save

그런 다음 app.module로 모듈을 Import합니다.

...
import { PipesModule } from 'w-ng5';

다음 단계에서 app.module의 선언 섹션을 추가합니다.

imports: [
  PipesModule,
  ...
]

사용 예

단순 문자열 필터링

<input type="text"  [(ngModel)]="filtroString">
<ul>
  <li *ngFor="let s of getStrings() | filter:filtroString">
    {{s}}
  </li>
</ul>

복합 문자열 필터링 - 레벨 2의 필드 '값'

<input type="text"  [(ngModel)]="search">
<ul>
  <li *ngFor="let s of getComplexTypesExtends() | filter:[{field:'n1.n2.valor2', value: search}]">
    {{s.nome}} - {{s.idade}} - {{s.n1.valor1}} - {{s.n1.n2.valor2}}
  </li>
</ul>

복합 문자열 필터링 - 중간 필드 - 레벨 1의 '값'

<input type="text"  [(ngModel)]="search3">
<ul>
  <li *ngFor="let s of getComplexTypesExtends() | filter:[{field:'n1.valor1', value: search3}]">
    {{s.nome}} - {{s.idade}} - {{s.n1.valor1}} - {{s.n1.n2.valor2}}
  </li>
</ul>

복잡한 배열 필터링 단순 - 필드 'Nome' 수준 0

<input type="text"  [(ngModel)]="search2">
<ul>
  <li *ngFor="let s of getComplexTypesExtends() | filter:[{field:'nome', value: search2}]">
    {{s.nome}} - {{s.idade}} - {{s.n1.valor1}} - {{s.n1.n2.valor2}}
  </li>
</ul>

트리 필드 필터링 - 레벨 2의 필드 'Valor', 레벨 1의 'Valor', 레벨 0의 'Nome'

<input type="text"  [(ngModel)]="search5">
<ul>
  <li *ngFor="let s of getComplexTypesExtends() | filter:[{field:'n1.n2.valor2', value: search5}, {field:'n1.valor1', value: search5}, {field:'nome', value: search5}]">
    {{s.nome}} - {{s.idade}} - {{s.n1.valor1}} - {{s.n1.n2.valor2}}
  </li>
</ul>

존재하지 않는 필드 필터링 - 존재하지 않는 수준 3의 '값'

<input type="text"  [(ngModel)]="search4">
<ul>
  <li *ngFor="let s of getComplexTypesExtends() | filter:[{field:'n1.n2.n3.valor3', value: search4}]">
    {{s.nome}} - {{s.idade}} - {{s.n1.valor1}} - {{s.n1.n2.valor2}}
  </li>
</ul>

이 구성 요소는 무한 특성 수준에서 작동합니다...

저는 여기와 다른 곳에서의 답을 바탕으로 플런커를 만들었습니다.

게다가, 나는, I'm servisor를 추가해야 했다.@Input,@ViewChild,그리고.ElementRef<input>작성 및 작성subscribe()관찰할 수 있는 것까지요

Angular2 검색 필터: PLUNKR(업데이트: PLUNKER는 더 이상 작동하지 않습니다)

상기의 매우 우아한 콜백 파이프 솔루션에 근거해, 추가의 필터 파라메타를 건네주는 것으로, 조금 더 일반화할 수 있습니다.다음으로 다음이 있습니다.

콜백.pipe.ts

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

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

요소

filterSomething(something: Something, filterArgs: any[]) {
  const firstArg = filterArgs[0];
  const secondArg = filterArgs[1];
  ...
  return <some condition based on something, firstArg, secondArg, etc.>;
}

html

<li *ngFor="let s of somethings | callback : filterSomething : [<whatWillBecomeFirstArg>, <whatWillBecomeSecondArg>, ...]">
  {{s.aProperty}}
</li>

코드는 다음과 같습니다.

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

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

샘플:

LIST = [{id:1,name:'abc'},{id:2,name:'cba'}];
FilterValue = 1;

<span *ngFor="let listItem of LIST | filter : 'id' : FilterValue">
                              {{listItem .name}}
                          </span>

애플리케이션 고유의 필터에 사용하는 또 다른 방법은 커스텀파이프(IMHO)를 사용하는 것보다 필터링 로직을 깔끔하게 캡슐화할 수 있는 커스텀 읽기 전용 속성을 컴포넌트에 사용하는 것입니다.

예를 들어, 에 바인드 하는 경우albumList필터링을 합니다.searchText:

searchText: "";
albumList: Album[] = [];

get filteredAlbumList() {
    if (this.config.searchText && this.config.searchText.length > 1) {
      var lsearchText = this.config.searchText.toLowerCase();
      return this.albumList.filter((a) =>
        a.Title.toLowerCase().includes(lsearchText) ||
        a.Artist.ArtistName.toLowerCase().includes(lsearchText)
      );
    }
    return this.albumList;
}

HTML에서 바인드하려면 읽기 전용 속성에 바인드하면 됩니다.

<a class="list-group-item"
       *ngFor="let album of filteredAlbumList">
</a>

특정 용도에 특화된 필터의 경우 필터와 관련된 로직을 컴포넌트와 함께 유지하므로 파이프보다 더 잘 작동합니다.

파이프는 전체적으로 재사용 가능한 필터에 더 적합합니다.

리스트에서 원하는 아이템을 얻기 위해 다음 파이프를 만들었습니다.

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

@Pipe({
  name: 'filter'
})
export class FilterPipe implements PipeTransform {

  transform(items: any[], filter: string): any {
    if(!items || !filter) {
      return items;
    }
    // To search values only of "name" variable of your object(item)
    //return items.filter(item => item.name.toLowerCase().indexOf(filter.toLowerCase()) !== -1);

    // To search in values of every variable of your object(item)
    return items.filter(item => JSON.stringify(item).toLowerCase().indexOf(filter.toLowerCase()) !== -1);
  }

}

소문자 변환은 대소문자를 구분하지 않는 방법으로 일치시킵니다.뷰에서 다음과 같이 사용할 수 있습니다.

<div>
  <input type="text" placeholder="Search reward" [(ngModel)]="searchTerm">
</div>
<div>
  <ul>
    <li *ngFor="let reward of rewardList | filter:searchTerm">
      <div>
        <img [src]="reward.imageUrl"/>
        <p>{{reward.name}}</p>
      </div>
    </li>
  </ul>
</div>

이를 위해 Angualr 2 파이프를 작성하는 것이 이상적입니다.하지만 당신은 이 묘기를 할 수 있어요.

<ng-container *ngFor="item in itemsList">
    <div*ngIf="conditon(item)">{{item}}</div>
</ng-container>

이것은 당신의 어레이입니다.

products: any = [
        {
            "name": "John-Cena",
                    },
        {
            "name": "Brock-Lensar",

        }
    ];

이것은 ngFor 루프 필터 기준입니다.

<input type="text" [(ngModel)]='filterText' />
    <ul *ngFor='let product of filterProduct'>
      <li>{{product.name }}</li>
    </ul>

원래 데이터를 보존하기 위해 filterProduct Instant of products를 사용하고 있습니다.모델_필터텍스트는 입력 상자로 사용됩니다.변경 세터 함수가 호출됩니다.setFilterText performProduct는 입력과 일치하는 결과만 반환합니다.대소문자를 구분하지 않는 경우는 소문자를 사용합니다.

filterProduct = this.products;
_filterText : string;
    get filterText() : string {
        return this._filterText;
    }

    set filterText(value : string) {
        this._filterText = value;
        this.filterProduct = this._filterText ? this.performProduct(this._filterText) : this.products;

    } 

    performProduct(value : string ) : any {
            value = value.toLocaleLowerCase();
            return this.products.filter(( products : any ) => 
                products.name.toLocaleLowerCase().indexOf(value) !== -1);
        }

다음 트릭을 실행할 수 있습니다.

<ng-container *ngFor="item in items">
    <div *ngIf="conditon(item)">{{ item.value }}</div>
</ng-container>

또는

<div *ngFor="item in items">
  <ng-container *ngIf="conditon(item)">{{ item.value }}</ng-container>
</div>

이 예는 제가 얼마 전에 만들고 블로그에 올린 것입니다. 여기에는 작업용 플랭크도 포함되어 있습니다.모든 객체 목록을 필터링할 수 있는 필터 파이프를 제공합니다.기본적으로 ngFor 규격 내에서 {key:value} 속성과 값을 지정하기만 하면 됩니다.

@NateMay의 답변과 크게 다르지 않습니다만, 비교적 상세하게 설명하고 있습니다.

이 경우 사용자가 입력한 텍스트(filterText)에 대해 배열 내 객체의 "label" 속성에 대해 다음과 같은 종류의 마크업을 사용하여 정렬되지 않은 목록을 필터링했습니다.

<ul>
  <li *ngFor="let item of _items | filter:{label: filterText}">{{ item.label }}</li>
</ul>

https://long2know.com/2016/11/angular2-filter-pipes/

「 」를해 필터를 하는 첫 번째 @Pipe 파일component.ts로 합니다.

your.component.ts를 표시합니다.

import { Component, Pipe, PipeTransform, Injectable } from '@angular/core';
import { Person} from "yourPath";

@Pipe({
  name: 'searchfilter'
})
@Injectable()
export class SearchFilterPipe implements PipeTransform {
  transform(items: Person[], value: string): any[] {
    if (!items || !value) {
      return items;
    }
    console.log("your search token = "+value);
    return items.filter(e => e.firstName.toLowerCase().includes(value.toLocaleLowerCase()));
  }
}
@Component({
  ....
    persons;

    ngOnInit() {
         //inicial persons arrays
    }
})

개인 객체의 데이터 구조:

person.ts.

export class Person{
    constructor(
        public firstName: string,
        public lastName: string
    ) { }
}

html 파일 보기:

your.component.displaces

    <input class="form-control" placeholder="Search" id="search" type="text" [(ngModel)]="searchText"/>
    <table class="table table-striped table-hover">
      <colgroup>
        <col span="1" style="width: 50%;">
        <col span="1" style="width: 50%;">
      </colgroup>
      <thead>
        <tr>
          <th>First name</th>
          <th>Last name</th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let person of persons | searchfilter:searchText">
          <td>{{person.firstName}}</td>
          <td>{{person.lastName}}</td>
        </tr>
      </tbody>
    </table>

발견했어요.ng2-search-filter는 오브젝트를 취득하여 일치하는 모든 오브젝트 속성에 대해 검색어를 적용합니다.

객체를 통과하는 필터를 만드는 방법을 찾고 있었는데 멀티 필터처럼 사용할 수 있습니다.

뷰티솔루션을 해봤어요

필터.pipe.ts

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

@Pipe({
  name: 'filterx',
  pure: false
})
export class FilterPipe implements PipeTransform {
 transform(items: any, filter: any, isAnd: boolean): any {
  let filterx=JSON.parse(JSON.stringify(filter));
  for (var prop in filterx) {
    if (Object.prototype.hasOwnProperty.call(filterx, prop)) {
       if(filterx[prop]=='')
       {
         delete filterx[prop];
       }
    }
 }
if (!items || !filterx) {
  return items;
}

return items.filter(function(obj) {
  return Object.keys(filterx).every(function(c) {
    return obj[c].toLowerCase().indexOf(filterx[c].toLowerCase()) !== -1
  });
  });
  }
}

컴포넌트.ts 를 참조해 주세요.

slotFilter:any={start:'',practitionerCodeDisplay:'',practitionerName:''};

componentet.syslog

             <tr>
                <th class="text-center">  <input type="text" [(ngModel)]="slotFilter.start"></th>
                <th class="text-center"><input type="text" [(ngModel)]="slotFilter.practitionerCodeDisplay"></th>
                <th class="text-left"><input type="text" [(ngModel)]="slotFilter.practitionerName"></th>
                <th></th>
              </tr>


 <tbody *ngFor="let item of practionerRoleList | filterx: slotFilter">...

으로 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ngFor에 기재되어 있다.

<li *ngFor="let item of list | slice:0:10; let i=index" class="dropdown-item" >{{item.text}}</li>

언급URL : https://stackoverflow.com/questions/34164413/how-to-apply-filters-to-ngfor

반응형