Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用于创建URLSearchParams的自定义Angular2修饰符_Angular_Typescript_Angular2 Http - Fatal编程技术网

用于创建URLSearchParams的自定义Angular2修饰符

用于创建URLSearchParams的自定义Angular2修饰符,angular,typescript,angular2-http,Angular,Typescript,Angular2 Http,我正在使用angular 2创建一个api服务,并创建了一些装饰器,通过一些可重用的功能帮助简化类接口 我希望我的所有服务方法都采用反映http请求查询参数的请求对象映射 例如: const request: SomeInterface = { param: 'value', otherParam: 'otherValue', }; 将被传递到一个类方法中,该类方法将使用这些键/值对作为http请求中的查询字符串参数 以最简单的形式,我希望这样的事情发生。此示例将不会执行,因为

我正在使用angular 2创建一个api服务,并创建了一些装饰器,通过一些可重用的功能帮助简化类接口

我希望我的所有服务方法都采用反映http请求查询参数的请求对象映射

例如:

const request: SomeInterface = {
    param: 'value',
    otherParam: 'otherValue',
};
将被传递到一个类方法中,该类方法将使用这些键/值对作为http请求中的查询字符串参数

以最简单的形式,我希望这样的事情发生。此示例将不会执行,因为SomeInterface不是Angular期望的搜索属性类型

public getSomething(search: SomeInterface) {
    this.http.get(url, {
        search: search,
    });
}
我创建了两个decorator,它们完成了将对象转换为
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
    装饰器替换

  • 由于上述原因,当我在实际的
    http.get
    调用中使用它时,我必须将
    submissionsRequest
    转换为
    URLSearchParams
  • 一切都是有效的,但是这是误导性的,因为我是说
    submissionsRequest
    在方法签名中是
    submissionsRequest
    类型,但事实上它是
    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;
        };
    };
    
    我想我不希望该服务的使用者不得不担心传递
    URLSearchParams
    的实例,我更希望在该服务中完成这项工作,但我也不希望我的服务方法使用错误的类型

    关于如何协调这一点,有什么建议或想法吗