2017-11-15 4 views
2

私はこのプロジェクトリストをJSONに持っています。プロジェクト名を検索し、他のフィールドを無視したいだけです。今私の問題は、他のフィールドも検索することです。他のフィールドに影響を与えずにパイプ内でのみプロジェクト名を使って検索するにはどうすればいいですか?ここで私が以下にしたことがあります。パイプで角をつけて使用するフィールドを1つだけ検索

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

...しかし

パイプ変換でソートやフィルタリングなどの作業を行うべきではありません。非常に頻繁に発生する1回の変更検出サイクルごとにパイプ変換がトリガされるため、必要に応じて変更検出サイクルごとに並べ替えとフィルタリングが再適用されるため、アプリのパフォーマンスが極端に低下します。実際、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> 

最初に、あなたのサービスメソッドが観測でプロジェクトを取得するために保存し、このコードを順を追ってするために、あなたは、フォームを作りますあなたの検索語を制御し、それを観測値に保存し、空の値で始めてデバウンスしてdistnct値を取得するように指示します(これはマイナーな最適化です。実際にすべての文字を検索し、彼らが素早く文字を入力して削除する場合は研究しないでください)。次に、これらの2つを新しい観測値に結合し、フィルタ関数にそれらをマップして、どちらかの項目が変更されるたびにプロジェクトがフィルタリングされるようにします。

元の問題は...これは現在、パイプとしての何かを汎用的に使用しているわけではないので、nameプロパティを明示的にフィルタリングすることも、上記の変換関数を使うこともできますそれを頻繁に使用する場合は、フィルター演算子でフィルター演算子を使用しないでください。

+0

ありがとうブライアン。私はあなたの提案を使用してみます。新しい情報をありがとう。 – Joseph

関連する問題