2017-08-24 9 views
2

角度2アプリで表形式の表示を何度か繰り返してデータに問題があります。私はそれが主な問題は、最初のコンポーネントの読み込み時に、一連のフィルタのデータをネットワークリクエストとして送信しているという事実に関連していると考えています。角度アプリで値をフィルタリングするよりエレガントな方法

基本的には、ポストリクエストのオブジェクト本体にキーと値のペアを渡すことができるMongo/Mongoose機能を使用しています。この機能は、渡された値に基づいてフィルタリングされたデータセットを返します。このコードは次のようになります。

private processType(name: string, value: any, body) 
{ 
    if (this.body[name] && !value) { 
      delete this.body[name]; 
     } else { 
      this.body[name] = { $in: value }; 
     } 
} 

これはすべて期待どおりです。しかし、私の現在の実装で理想的ではないと感じるのは、初期コンポーネントのロード時に、これらの各フィルタのすべての可能な値の配列を渡していることです。そこから、ユーザは、UIフィルタリストを介して渡されフィルタリングされた内容を変更することができます。空の配列に渡すと何も一致しないので、最初のコンポーネントのロード時に、各フィルタの可能な値の配列全体を渡しています。しかし、私の最初のリクエストを処理するには、より良い方法があるはずです。

私が今やっているように、「最初はすべてをフィルタリングするのではなく」効果的に「最初はフィルタリングしない」という私の最初の要求が理想的です。初期ロード時の条件とユーザーがフィルターを削除する状況、またはすべてのフィルターを処理するのはちょっと手間がかかりますので、今のところこのようにしています。今、どちらのシナリオでも、すべての可能な値の配列をもう一度渡しています。私が働いているものは、それができるほどエレガントではないようです。これはすべてポストリクエストの本体でオブジェクトとして渡されるため、すべての値の配列を持つオブジェクトを渡すのではなく、単にオブジェクトを削除できる方法はありますか?

これは私の関連するコードの残りの部分は次のようになります。

public initLanguageFilterOptions(): void 
{ 
    this.languageFilterOptions = new FilterOptions([ 
     { value: 'English', toString:() => 'English' }, 
     { value: 'Spanish', toString:() => 'Spanish' }, 
     { value: 'Mandarin', toString:() => 'Mandarin' } 
    ]); 

    let arr = []; 

    // Update array when filter selection is made 
    arr.push(this.languageFilterOptions.addEventListener(FilterOptions.CHANGE_EVENT,() => this.sendLangSelections(true))); 

    // Update array when filter options are loaded from URL parameters 
    arr.push(this.languageFilterOptions.addEventListener(FilterOptions.URL_LOAD_EVENT,() => this.sendLangSelections(true))); 

    // Clean up after component is no longer used 
    this.addEventListener('ngOnDestroy', function() 
    { 
     arr.forEach(s => s()); // Remove all listeners 
     return true; 
    }.bind(this)); 

} 

/** 
* Handles the emitting of the selected values to the API 
*/ 
private sendLangSelections(languageFilterOptions) { 
    const origLangArray = ['English', 'Spanish', 'Mandarin']; 
    if (languageFilterOptions) 
     { 
      let selectionsArray = this.languageFilterOptions.selection; 
      let values = selectionsArray.map((a) => { return a.value; }); 
      if (values && values.length > 0) 
       { 
        this.sendLanguage.emit(values); 
       } 
      else if (values && values.length < 1) 
       { 
        this.sendLanguage.emit(origLangArray); 
       } 
     } 
} 

これが私たちのモンゴ/マングース/ノードのバックエンドへの私のAPIの呼び出しは次のようになります。これを行うには

// A POST request to work with observables 
public obsPost(strReq, page, pagesize, body, sort?) { 
    const headers = new Headers({ 'Content-Type': 'application/json' }); 
    const options = new RequestOptions({ headers: this.headers }); 
    return this.http.post 
    (`${API.URL}/${API.VER}${strReq}?apikey=${API.KEY}&page=${page}&pagesize=${pagesize}`, 
    body, options) 
     .map((res: Response) => res.json()) 
     .catch(this.filterErrorHandler); 
} 
    filterErrorHandler(error: Response) { 
    console.error(error); 
    return Observable.throw(error.json().error || 'Server error'); 
} 

答えて

1

{ $in: value }を介して値が渡されるときに、より多くの条件付きロジックを追加することになります。ポップアップしていたエラーは{ $in: value }の書式設定の問題が原因だったため、キーは渡される値がある場合にのみトリガーされるようにしました。

private processType(name: string, value: any, body) 
{ 
    if (this.body[name] && !value) { 
      delete this.body[name]; 
     } else { 
      this.body[name] = { $in: value }; 
     } 
} 

..: - エレガントでもパフォーマンスの高いソリューションではありませんでしたすべての可能な値の配列を渡すことなく -

だから、最後に、この作業を取得するために私はこれを変更しました。これは、{$ in:value}がトリガされたときに、少なくとも1つの値の配列が使用可能であることを基本的に保証します。

変更が必要なのは、ユーザーがすべての値を選択解除したときに放出される内容のみでした。私はそれをこのように扱いました:

private sendLangSelections(languageFilterOptions) { 
    const origLangArray = ['English', 'Spanish', 'Mandarin']; 
    if (languageFilterOptions) 
     { 
      let selectionsArray = this.languageFilterOptions.selection; 
      let values = selectionsArray.map((a) => { return a.value; }); 
      if (values && values.length > 0) 
       { 
        this.sendLanguage.emit(values); 
       } 
      else if (values && values.length < 1) 
       { 
        this.sendLanguage.emit(this.obj = undefined); 
       } 
     } 
} 
関連する問題