2017-11-15 11 views
2

이 프로젝트 목록은 JSON에 포함되어 있으므로 프로젝트 이름을 검색하고 다른 필드는 무시하고 싶습니다. 내 문제는 이제 다른 필드를 검색한다는 것입니다. 어떻게 다른 필드가 영향을 미치지 않고 내 파이프에서만 프로젝트 이름을 사용하여 검색을 수행 할 수 있습니까? 여기에 내가 한 일이 있습니다.파이프를 각도로 사용하여 하나의 필드 만 검색

JSON

{ 
    "token": "ejsk0e", 
    "projects": [ 
    { 
     "id": 5, 
     "name": "Store", 
     "description": "Small", 
     "organization_id": 1, 
     "created_at": "2017-10-29 10:31:50", 
     "updated_at": "2017-11-14 06:27:03", 
     "material_projects": [ 
     { 
      "id": 18, 
      "material_id": 40, 
      "project_id": 5, 
      "quantity": 10, 
      "unit": "pcs", 
      "created_at": "2017-11-02 09:57:14", 
      "updated_at": "2017-11-02 09:57:14", 
      "material": { 
      "id": 40, 
      "sku": "ACWNAIL", 
      "name": "Banana", 
      "created_at": "2017-10-26 03:19:54", 
      "updated_at": "2017-10-26 03:23:21" 
      }, 
      "categories": [ 
      { 
       "id": 8, 
       "name": "Fruits", 
       "created_at": "2017-10-26 07:36:48", 
       "updated_at": "2017-11-10 02:06:07", 
       "pivot": { 
       "material_proj_id": 18, 
       "category_id": 8 
       } 
      } 
      ], 
      "material_name": "Banana", 
      "material_sku": "ACWNAIL", 
      "category_name": "Fruits" 
     } 
    ] 
} 

TS

getAllProjects() { 
    this.subscription = this.projectsService.getAll() 
     .subscribe(
     (data:any) => { 
      this.projects = data.projects; 
     }, 
     error => { 
      console.log(error); 
     }); 
    } 

HTML

,
<div class="container-fluid"> 
    <input placeholder="Search..."" type="text" [(ngModel)]="searchProj"> 
    <div class="row" *ngFor="let project of projects | search : searchProj"> 
    <div class="card-block"> 
     <h2 class="proj-name">{{ project.name }}</h2> 
    </div> 
    </div> 
</div> 

PIPE.ts

export class SearchPipe implements PipeTransform { 

     transform(items: any, term: any): any { 
     if (term === undefined) return items; 

     return items.filter(function(item) { 
      for(let property in item){ 
      if (item[property] === null){ 
       continue; 
      } 
      if(item[property].toString().toLowerCase().includes(term.toLowerCase())){ 
       return true; 
      } 
      } 
      return false; 
     }); 
     } 
    } 
+1

필터링 작업에 파이프를 사용해서는 안되며, 필터링은 CPU 집약적 인 작업이며 필요에 따라 파이프 변경은 모든 단일 변경 감지주기에 트리거됩니다.이 방법은 응용 프로그램 성능이 저하 될 수 있으므로 더 나은 방법은 관찰 가능 항목을 사용하는 것입니다 필요할 때만 필터링을 실행합니다. – bryan60

답변

0

문제에 대한 해결 방법은 당신의 파이프에 변수와 속성을 공급하는 것입니다 그러나

transform(items: any, term: any, prop: string): any { 
    if (!term || !prop) return items; 

    return items.filter((item) => 
     item[prop].toString().toLowerCase().includes(term.toLowerCase())); 
    } 


<div class="row" *ngFor="let project of projects | search : searchProj : 'name'"> 

...

파이프 변환에서 정렬 및 필터링과 같은 작업을해서는 안됩니다. 파이프 변환은 매우 자주 발생하는 하나의 변경 감지주기마다 트리거하므로 필요하거나 불필요한 모든 변경 감지주기에 정렬 및 필터링이 다시 적용되므로 앱 성능이 극도로 떨어집니다. 실제로, angularJS에는 필터 파이프가 포함되었지만 널리 분산 된 악용으로 인해 제거되어 응용 프로그램 성능이 저하되었습니다. 더 좋은 방법은 변경 감지에 의존하는 대신 정렬 또는 필터링을 트리거해야 할 때의 논리를 구축하는 것입니다.

이 방법은 ngModel 대신 반응 형을 사용하는 것이 더 쉽기 때문에 내 견본에서이를 사용합니다.

TS :

this.projects$ = this.projectsService.getAll(); 
this.searchProj = new FormControl(''); 
this.search$ = this.searchProj.valueChanges.startWith('').debounce(300).distinctUntilChanged(); 
this.filteredProjects$= Observable.combineLatest(this.projects$, this.search$) 
            .map(([projects, searchTerm]) => (searchTerm) ? projects.filter(p => p.name.toString().toLowerCase().includes(searchTerm.toLowerCase()) : projects); 

는 다음 HTML :

<div class="container-fluid"> 
    <input placeholder="Search..."" type="text" [formControl]="searchProj"> 
    <div class="row" *ngFor="let project of filteredProjects$ | async"> 
    <div class="card-block"> 
     <h2 class="proj-name">{{ project.name }}</h2> 
    </div> 
    </div> 
</div> 

먼저 당신은 관찰에서 프로젝트를 검색하는 서비스 방법을 저장,이 코드를 안내하기 위해, 다음 폼 만들기 귀하의 검색 용어에 대한 컨트롤을 누른 다음 값을 변경하는 방법을 observable에 저장하고, 먼저 빈 값으로 시작한 다음 디버그하여 distnct 값만 가져옵니다 (이것은 사용자가 신속하게 유형을 입력하면 실제로 모든 문자 쌍을 검색하고 그들이 신속하게 캐릭터를 입력하고 제거하는 경우 조사하지 마십시오.) 그런 다음 두 개의 새로운 관측 가능 객체를 결합하고 두 필터 함수를 함께 매핑하여 항목이 변경 될 때마다 프로젝트가 필터링되도록합니다.

원래 문제는 ... 파이프가 아닌 일반 용도로 사용하지 않기 때문에 이름 속성을 명시 적으로 필터링하거나 위의 변환 함수를 사용할 수 있습니다. 자주 사용하는 경우 맵핑 연산자에서 필터링 논리를 반복하지 마십시오.

+0

감사합니다. 많은 브라이언. 나는 너의 제안을 사용하려고 노력할 것이다. 새로운 정보를 가져 주셔서 감사합니다. – Joseph