2017-12-11 9 views
1

私は、オブジェクトの配列を表示するngForを持つページがあるプロジェクトで作業しています。私は、入力フィールドに特定のキーワードを入力することによって、これらのオブジェクトをフィルタリングする機能をユーザーに与えたいと考えています。角4 - フィルタリング中に200ミリ秒ごとにHTTPリクエストを1つに制限する

データのフィルタリングはサーバー側で行う必要があるため、私はこのサービスを私のサービスで実装しました。

public searchProperties(query: string): Observable<IProperty[]> { 
    console.log('SERVICE: query: ' + query); 
    let params = new HttpParams(); 

    params = params.append('q', query); 

    return this.http.get<IProperty[]>(this.baseUrl+'/api/property', {params: params}) 
    .do(response => { 
     console.log('Successfully retrieved the search response'); 
    }).catch((error: HttpErrorResponse) => { 
     console.log('Something went wrong while retrieving the search response'); 
     return Observable.throw(error); 
    }) 
    } 

私はこのようなパイプでこのメソッドを呼び出します。

transform(items: IProperty[], searchText: string): any[] { 
    if(!items) return []; 
    if(!searchText) return items; 

    console.log('PIPE: Amount of items in items array BEFORE: ' + items.length); 

    this.propertyService.searchProperties(searchText).subscribe(
     result => { 
     items = result; 
     }, error => { 
     console.log('Failed to retrieve the properties that were searched for'); 
     return items; 
     }, 
    () => { 
     console.log('PIPE: Amount of items in items array AFTER: ' + items.length); 
     return items; 
     } 
    ) 
    } 

私はこのようなHTMLで私ngForにパイプを追加しました:

<div class="col-md-4" *ngFor="let property of properties | property_filter : searchText ; let i=index"> 

私には二つの問題があります。現在のコード:

  1. ev入力フィールドにキーワードを入力すると、httpコールが呼び出され、パイプへの応答が返されますが、ページにはオブジェクトが表示されません。入力フィールドを再度クリアするまで、ngForは空のままです。

  2. 入力中に、HTTP呼び出しは、1回の変更イベントではなく、200ミリ秒ごとにオフにする必要があります。

ありがとうございます!

UPDATE:

Iパイプを削除し、コンポーネントにコールを実施しました。オブジェクトのリストが正しく更新されるようになりました。

残っている唯一の質問は、応答の量を200ミリ秒ごとに1つに制限する方法です。

+0

あなたは 'autocomplete'を再実装していますか?このパッケージを見てくださいhttps://www.npmjs.com/package/ng2-auto-complete –

+0

なぜあなたはあなたのパイプ変換コードでサービスを使用して再びフィルタリングするよりもプロパティ配列を渡している場合??? –

+0

あなたはパイプを間違った方法で使用しようとしているようです –

答えて

0

あなたの変更後にイベントを発生させるには、次のようにRxJsのdebounceTime機能を使用します。

<input type="text" [ngModel]="term" (ngModelChange)="change($event)"/> 

import { Subject } from 'rxjs/Subject'; 
import { Component } from '@angular/core'; 
import 'rxjs/add/operator/debounceTime'; 

export class AppComponent{ 
    term: string; 
    modelChanged: Subject<string> = new Subject<string>(); 

    constructor() { 
     this.modelChanged 
     .debounceTime(300) // wait 300ms after the last event before emitting last event 
     .distinctUntilChanged() // only emit if value is different from previous value 
     .subscribe(model => this.model = model); 
    } 

    change(text: string) { 
     this.modelChanged.next(text); 
     //code for filtering goes here 
    } 
} 


____ 

後、私は、サーバーからのフィルタリングメールアドレスに使用私のコードと、それが正常に動作し

Pipe.ts

import { Pipe, PipeTransform } from '@angular/core'; 
import { ReportService } from './ReportService'; 
import { Observable } from 'rxjs/Observable'; 

@Pipe({ 
    name: 'filter' 
}) 

export class MyFilter implements PipeTransform { 
    emails: Array<string>= new Array<string>(); 
    constructor(private reportservice :ReportService) 
    {} 

    transform(items: any[], term: string): any { 
     debugger; 
     if (!term) 
     return items; 
     this.reportservice.GetAllEmails().subscribe(e=> this.emails = e); 
     return this.emails.filter(item => item.indexOf(term) > -1); 
    } 
} 

App.Component.Html

です
<form id="filter"> 
    <label>Searching for email</label> 
    <input type="text" name="termtext" [(ngModel)]="term" /> 
</form> 

<ul *ngFor="let email of emails| filter:term"> 
    {{email}} 
</ul> 

アプリ.component.ts

最初にサーブからの取り出しデータとして時間がかかるが、次回は正常に動作する。

+0

入力に値を入力するたびに、与えられた時間後に同時に発砲する。 – DennisN

+0

@DennisN - それはdebounceTimeが動作しているので、あらかじめ定義された時間にすべての入力値を一度に送信します...あなたは何を望みますか? –

+0

私は実際には1人だけが解雇されることを望んでいます。私は入力フィールドを持っていて、入力に文字を入力するたびにリクエストが送信されます。入力時に多くのリクエストが送信されないように、各キーダウンイベントの後200ms待つコンポーネントが必要ですが、最新のものだけです – DennisN

関連する問題