前言
在前後端開發中,資料傳輸格式的一致性是至關重要的。尤其是在不同程式語言之間傳遞資料時,欄位命名規則的不同可能會導致前端無法正確解析後端返回的資料。我們知道一般欄位的命名規則一般是 駝峰式 和 下劃線 的方式,一般情況下 下線劃 是定義mysql 屬性欄位的時候使用,而 java 跟 ts 基本都是採用駝峰式命名。
為了解決這個前端無法正確解析後端返回的資料,使用 class-transformer 可以幫助我們在物件轉換時處理欄位命名的差異,確保前端能夠正確接收到資料。
使用 class-transformer 進行欄位轉換
- 定義 user 實體
export class User {
id: number;
name: string;
username: string;
createdAt: string;
updatedAt: string;
constructor(
id: number,
name: string,
username: string,
createdAt: string,
updatedAt: string
) {
this.id = id;
this.name = name;
this.username = username;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}
}
- 定義mock api
import {ApiInjector, MockApiInterface} from "@yunzhi/ng-mock-api";
export class UserApi implements MockApiInterface {
getInjectors(): ApiInjector[] {
return [
{
method: 'GET',
url: '/user/getById/:id',
description: '任務列表',
// 模擬返回的資料
result: {
id: 1,
name: '張三',
username: 'zhangsan',
created_at: '2021-01-01 00:00:00',
updated_at: '2021-01-01 00:00:00'
}
}
];
}
}
- 實現服務
import { Injectable } from '@angular/core';
import {HttpClient} from "@angular/common/http";
import {Observable} from "rxjs";
import {User} from "../entity/user";
@Injectable({
providedIn: 'root'
})
export class UserService {
constructor(private httpClient: HttpClient) {
}
getById(id: number): Observable<User> {
return this.httpClient.get<User>(`/user/getById/${id}`);
}
}
- 元件中使用服務
@Component({
selector: 'app-root',
template: `
<div *ngIf="user">
<h1>名稱:{{ user.name }}</h1>
<p>使用者名稱: {{ user.username }}</p>
<p>建立時間: {{ user.createdAt }}</p>
<p>修改時間: {{ user.updatedAt }}</p>
</div>
`
})
export class AppComponent implements OnInit{
user: User = {} as User;
constructor(private userService: UserService) {
}
ngOnInit(): void {
this.userService.getById(1).subscribe((user: User) => {
this.user = user;
});
}
}
這裡我發現當前 createdAt 和 updatedAt 無法接收到值
- 安裝 class-transformer
npm install class-transformer
配置tsconfig.json檔案以支援裝飾器
{
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true
}
}
- 重構 user 實體
import { Expose } from 'class-transformer';
export class User {
id: number;
name: string;
username: string;
@Expose({ name: 'created_at' })
createdAt: string; // 保持為字串型別
@Expose({ name: 'updated_at' })
updatedAt: string; // 保持為字串型別
}
- 接收到的值進行轉換
this.userService.getById(1).subscribe((user: User) => {
this.user = plainToInstance(User, user);
});
到這裡我們發現這個就可以解決轉換問題了
總結
到這裡我們解決欄位不一致的問題,這個功能很像 JAVA 使用 @JsonAlias 註解 使用起來很方便