2017-08-10 61 views
1

我如何複雜的對象轉換爲查詢字符串用於的WebAPI:轉換複雜對象查詢字符串

export enum FilterCondition { 
    Equal, 
    NotEqual, 
    GreaterThan, 
    LessThan, 
    GreaterThanEqual, 
    LessThanEqual 
} 

export class QueryParameter { 
    propertyName: string; 
    filterCondition: FilterCondition 
    value: string; 
} 

export class QueryOptions { 
    queryParameters: QueryParameter[] = new Array<QueryParameter>(); 
} 

我想編寫一個通用的功能到複雜的類型轉換爲基本查詢 我寫的這個函數轉換一個簡單的對象查詢字符串

export class QueryStringBuilder { 
    static BuildParametersFromSearch<T>(obj: T): URLSearchParams { 
     let params: URLSearchParams = new URLSearchParams(); 

     const objectKeys = Object.keys(obj) as Array<keyof T>; 
     for (let key of objectKeys) { 
      params.set(key, obj[key]) 
     } 

     return params; 
    } 
} 

但我有麻煩抓我怎麼能與枚舉和數組等複雜的對象做到這一點遞歸?任何人都可以指向正確的方向,或者已經做到了這一點?

回答

2

因爲任何人想知道如何做到這一點,我寫了一個擴展,應該與c#.Net Core 1.1和Typescript 2.2.2 WebApi一起工作,看起來像這樣。

記住,你正在使用它,以及

import { URLSearchParams } from '@angular/http'; 
import 'rxjs/add/operator/map' 

export class QueryStringBuilder { 
    static BuildParametersFromSearch<T>(obj: T): URLSearchParams { 
     let params: URLSearchParams = new URLSearchParams(); 

     if (obj == null) 
     { 
      return params; 
     } 

     QueryStringBuilder.PopulateSearchParams(params, '', obj); 

     return params; 
    } 

    private static PopulateArray<T>(params: URLSearchParams, prefix: string, val: Array<T>) { 
     for (let index in val) { 
      let key = prefix + '[' + index + ']'; 
      let value: any = val[index]; 
      QueryStringBuilder.PopulateSearchParams(params, key, value); 
     } 
    } 

    private static PopulateObject<T>(params: URLSearchParams, prefix: string, val: T) { 
     const objectKeys = Object.keys(val) as Array<keyof T>; 

     if (prefix) { 
      prefix = prefix + '.'; 
     } 

     for (let objKey of objectKeys) { 

      let value = val[objKey]; 
      let key = prefix + objKey; 

      QueryStringBuilder.PopulateSearchParams(params, key, value); 
     } 
    } 

    private static PopulateSearchParams<T>(params: URLSearchParams, key: string, value: any) { 
     if (value instanceof Array) { 
      QueryStringBuilder.PopulateArray(params, key, value); 
     } 
     else if (value instanceof Date) { 
      params.set(key, value.toISOString()); 
     } 
     else if (value instanceof Object) { 
      QueryStringBuilder.PopulateObject(params, key, value); 
     } 
     else { 
      params.set(key, value.toString()); 
     } 
    } 
} 

這是工作的所有複雜類型到目前爲止,我已經使用,包括這兩個進口。

編輯用法我已經包括了所有的import語句我認爲重要的是RequestOptionsArgs,RequestOptions的,但我記得他們需要這樣只是櫃面我已經包括了他們所有人。

import { Injectable } from '@angular/core'; 
import { Http, Headers, RequestOptionsArgs, RequestOptions } from '@angular/http'; 
import { Observable } from 'rxjs/Rx'; 
import { IHasId } from '../interfaces/interfaces'; 
import 'rxjs/add/operator/map'; 

import { QueryOptions, IFilterNode } from "../models/queryOptions"; 
import { QueryStringBuilder } from "../models/QueryStringBuilder"; 

import 'rxjs/add/operator/map' 

@Injectable() 
export class ProviderBase<T extends IHasId> { 

    getList(filterParams?: IFilterNode): Observable<T[]> { 
     var searchParams = QueryStringBuilder.BuildParametersFromSearch(filterParams); 

     let requestArguments: RequestOptionsArgs = new RequestOptions({ search: searchParams }); 
     return this.http.get(`${this.apiUrl}/${this.route}`, requestArguments).map(res => <T[]>res.json()); 
    } 
} 
+0

的利用方法可能是有用的也 –

+1

@RobMcCabe我會後一個在一秒鐘。必須在我的github上找到它 –

+0

@RobMcCabe我已經更新,包括一個示例用法,一些導入是必需的IHasId是我自定義的,所以你可以忽略那個等 –

相關問題