我正在使用angular 2创建一个api服务,并创建了一些装饰器来帮助简化类接口以及一些可重用的功能。
我希望我的所有服务方法都能获取一个镜像http请求查询参数的请求对象映射。
例如:
const request: SomeInterface = {
param: 'value',
otherParam: 'otherValue',
};
将传递给一个类方法,该方法将这些键/值对用作http请求中的查询字符串参数。
以最简单的形式,我想要这样的事情发生。此示例将不会执行,因为SomeInterface不是Angular对搜索属性所期望的类型。
public getSomething(search: SomeInterface) {
this.http.get(url, {
search: search,
});
}
我创建了两个装饰器来完成将对象转换为URLSearchParams
的实例。
import { URLSearchParams } from '@angular/http';
export function UrlSearchParams() {
return function UrlSearchParams(target: any, methodName: string, index: number) {
const metadataKey = `__urlSearchParams_${methodName}__`;
target[metadataKey] = [index];
};
};
export function NgServiceMethod() {
return function NgServiceMethod(target, methodName, descriptor) {
if (!descriptor) {
descriptor = Object.getOwnPropertyDescriptor(target, methodName);
}
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
const metadataKey = `__urlSearchParams_${methodName}__`;
const parameter = target[metadataKey];
const searchParams = new URLSearchParams();
const request = args[parameter];
for (const key in request) {
if (request.hasOwnProperty(key)) {
searchParams.set(key, key);
}
}
args[parameter] = searchParams;
return originalMethod.apply(this, args);
};
return descriptor;
};
};
以下是它的实例。
import { NgServiceMethod, UrlSearchParams } from '../shared/express/url-search-params.decorator';
import * as process from 'process';
import { SubmissionsRequest } from './submissions-request.model';
import { Injectable } from '@angular/core';
import { Http, URLSearchParams, Headers } from '@angular/http';
@Injectable()
export class SubmissionsApiService {
private submissionsApiUrl: string = '/social-submissions';
constructor(private http: Http) { ; }
@NgServiceMethod()
public listSubmissions( @UrlSearchParams() submissionsRequest: SubmissionsRequest) {
const headers = new Headers({
'X-API-KEY': process.env.SUBMISSIONS_API_KEY,
});
return this.http.get(this.submissionsApiUrl, {
search: submissionsRequest as URLSearchParams,
headers: headers,
});
}
}
这很有效。然而,我正在努力解决一些挑剔的问题。
我希望服务方法签名接受带有请求对象接口的参数。在工作示例的情况下,SubmissionsRequest
的实例。不幸的是,实际传递函数的是URLSearchParams
的一个实例,因为它被UrlSearchParams
装饰器取代。
submissionsRequest
电话中使用URLSearchParams
时http.get
。 一切正常,但这会产生误导,因为我说方法签名中的submissionsRequest
类型为SubmissionsRequest
,但实际情况是URLSearchParams
类型。
我想我不希望服务的消费者不必担心传递URLSearchParams
的实例而宁愿在服务中做这项工作,但我也不想要我的服务方法使用错误的类型。
关于如何调和此问题的任何建议或想法?