Angular 6中如何将API下划线字段映射为小驼峰命名模型?
这里有几种靠谱的方法帮你把API返回的蛇形命名字段映射到你的小驼峰Client模型上,每种方法都有对应的代码示例,你可以根据自己的场景选择:
方案1:手动使用RxJS的map操作符转换
这是最直接的方式,不需要额外依赖,适合字段不多的简单场景。你只需要在现有的pipe链里添加一个map操作,把每个API返回的对象转换成符合Client模型的结构:
// 先定义一个接口描述API返回的数据结构(可选,但能提升类型安全性) interface ApiClient { id: number; legal_name: string; trade_name: string; created_at: string; updated_at: string; } getClients(): Observable<Client[]> { return this.http.get<ApiClient[]>(this.clientsUrl, { headers: httpOptions.headers, observe: 'body', responseType: 'json' }).pipe( // 转换每个API返回的对象到Client结构 map(apiClients => apiClients.map(client => ({ legalName: client.legal_name, tradeName: client.trade_name, id: client.id, createdAt: new Date(client.created_at), // 可选:把字符串转成Date对象 updatedAt: new Date(client.updated_at) }))), // 优化日志输出,显示获取到的客户数量而非对象字符串 tap(clients => this.log(`${clients.length} fetched clients`)), catchError(this.handleError('getClients', [])) ); }
方案2:给Client类添加静态转换方法
如果这个转换逻辑需要在多个地方复用,给Client类加一个静态方法会让代码更整洁,也方便后续维护:
首先更新你的Client类:
export class Client { public id?: number; public tradeName: string; public legalName: string; public createdAt?: Date; public updatedAt?: Date; constructor(legalName: string, tradeName: string, id?: number, createdAt?: Date, updatedAt?: Date) { this.legalName = legalName; this.tradeName = tradeName; this.id = id; this.createdAt = createdAt; this.updatedAt = updatedAt; } // 静态方法:从API返回的蛇形对象创建Client实例 static fromApi(apiClient: ApiClient): Client { return new Client( apiClient.legal_name, apiClient.trade_name, apiClient.id, new Date(apiClient.created_at), new Date(apiClient.updated_at) ); } }
然后修改getClients函数:
getClients(): Observable<Client[]> { return this.http.get<ApiClient[]>(this.clientsUrl, { headers: httpOptions.headers, observe: 'body', responseType: 'json' }).pipe( map(apiClients => apiClients.map(Client.fromApi)), tap(clients => this.log(`${clients.length} fetched clients`)), catchError(this.handleError('getClients', [])) ); }
方案3:使用class-transformer库自动转换
如果你的模型有很多字段或者嵌套结构,手动转换会很繁琐,这时可以用class-transformer这个库来自动处理蛇形和驼峰的转换:
首先安装依赖:
npm install class-transformer
然后更新Client类,用装饰器标记字段映射:
import { Expose, Transform, plainToInstance } from 'class-transformer'; export class Client { @Expose({ name: 'id' }) public id?: number; @Expose({ name: 'trade_name' }) public tradeName: string; @Expose({ name: 'legal_name' }) public legalName: string; @Expose({ name: 'created_at' }) @Transform(({ value }) => new Date(value)) // 自动把字符串转成Date对象 public createdAt?: Date; @Expose({ name: 'updated_at' }) @Transform(({ value }) => new Date(value)) public updatedAt?: Date; }
最后修改getClients函数:
getClients(): Observable<Client[]> { return this.http.get<any[]>(this.clientsUrl, { headers: httpOptions.headers, observe: 'body', responseType: 'json' }).pipe( map(apiClients => plainToInstance(Client, apiClients)), tap(clients => this.log(`${clients.length} fetched clients`)), catchError(this.handleError('getClients', [])) ); }
小提示
- 如果你不需要
id、created_at这些字段,可以在转换时忽略它们,只保留你需要的legalName和tradeName。 - 原来的日志语句
this.log(clients + ' fetched clients')会把数组转成[object Object]...的模糊字符串,改成${clients.length} fetched clients会更直观。
内容的提问来源于stack exchange,提问作者Raul Espinosa
相关产品推荐
相关产品推荐

