如何将JSON对象转换为TS类

问题描述 投票:0回答:4

我正在尝试将 Django 响应转换为 Angular 的

User
数组。有几个原因,例如不同的变量名称(
first_name
vs
firstName
)以及 Angular
User
构造函数内部有一些逻辑。

简单 Django

User
=> Angular
User

服务器响应示例:

[
  {"id":2,"email":"[email protected]","first_name":"Name 1","client":{"id":1}}},
  {"id":3,"email":"[email protected]","first_name":"Name 2","client":{"id":2}}}
]

我想要的是转换成这种格式:

export class User {
    // contructor that transforms
    id: number;
    email: string;
    firstName: string;
    isClient: boolean = false;
}

我目前已经“解决”了这个问题,但我想知道是否有更好的解决方案。

内部

something.service.ts

public getClients(): Observable<User[]> {
    return this.http.get(this.getClientsUrl)
    .map(r => r.json() || []).map(x => x.map(y => new User(y)));
}

当我说更好的解决方案时,虽然这有效,但它看起来不太可读。如果您执行一次,这不是问题,但是当您有很多请求时,您会开始考虑更好的解决方案(处理此问题的一种方法?)。什么是更好的方法?类似拥有的东西

return this.http.get(this.getClientsUrl)
.map(transformResponse);
angular typescript
4个回答
0
投票

应该是这样的

return this.http.get(this.getClientsUrl)
.map(r => this.transformResponse(r));

0
投票

TS 界面如下所示:

interface SquareConfig {
    color: string;
    width?: number;
    enabled: boolean;
}

您想要将给定对象转换为 TS 接口(真的)还是想让响应对象更具可读性?这完全不一样啊。
因为上面的例子“我想要的”不是TS接口。


0
投票

如果您以不同的方式格式化代码并使用更明确定义的名称,那么它会更具可读性,例如

public getClients(): Observable<User[]> {
    return this.http.get(this.getClientsUrl)
        .map(response => response.json() || [])
        .map(users => users.map(user => new User(user)));
}

我创建了一个 codepen 示例,它会注销格式正确的服务器响应。

从另一个答案中阅读您的评论:

类似这样的东西,但我希望transformResponse只实现一次,这意味着它也应该接受类作为参数。

我认为你想要TypeScript泛型,它可能看起来像这样:

public getClients<T>(type: T): Observable<T[]> {
    return this.http.get(this.getClientsUrl)
        .map(response => response.json() || [])
        .map(clients => clients.map(client => new type(user)));
}

如果你想结合 Roman C 的方法:

public getClients(): Observable<User[]> {
    return this.http.get(this.getClientsUrl)
        .map(response => response.json() || [])
        .map(users => users.map(user => this.mapServerResponse<User>(user, User)));
}

mapServerResponse<T>(response, type: T): T {
    return new type(response);
}

0
投票

我发现的一个解决方案(在 Roman C 的想法的帮助下)是扩展

Service
类。此解决方案适用于
Array
Object
响应。

export class ServiceUtils {
    protected transformResponse(response: Response, myClass: any) {
        let body = response.json();

        if (body.constructor === Array) {
            return body.map(element => new myClass(element)) || []
        } 

        return new myClass(body) || new myClass();
    }
}

使用方法如下:

export class SomeService extends ServiceUtils {

    constructor(private http: Http) {
        super(); // Unfortunate side effect
     }

    public getClients(): Observable<User[]> {
        return this.http.get(this.getClientsUrl)
        .map(response => this.transformResponse(response, User));
    }
}

编辑:

更好的解决方案(无需扩展

Service
):

import { Response } from '@angular/http';


export class ServiceUtils {
    public static transformResponse(response: Response, myClass: any) {
        let body = response.json();

        if (body.constructor === Array) {
            return body.map(element => new myClass(element)) || []
        } 

        return new myClass(body) || new myClass();
    }
}

并使用它:

public getClients(): Observable<User[]> {
    return this.http.get(this.getClientsUrl)
    .map(r => ServiceUtils.transformResponse(r, User));
}
© www.soinside.com 2019 - 2024. All rights reserved.