มันเป็นยุค ES6 และ Typescript ทุกวันนี้คุณกำลังทำงานกับคลาสและอ็อบเจ็กต์คอนสตรัคเตอร์มากขึ้นกว่าเดิม Class-transformer ช่วยให้คุณสามารถแปลงวัตถุธรรมดาไปเป็นอินสแตนซ์ของคลาสและในทางกลับกัน นอกจากนี้ยังอนุญาตให้ซีเรียลไลซ์ / ดีซีเรียลไลซ์วัตถุตามเกณฑ์ เครื่องมือนี้มีประโยชน์อย่างยิ่งทั้งกับส่วนหน้าและส่วนหลัง
ตัวอย่างวิธีใช้กับ เชิงมุม 2 ในพลั่วเกอร์ ซอร์สโค้ดมีอยู่ที่นี่
ใน JavaScript มีวัตถุสองประเภท:
วัตถุธรรมดาเป็นวัตถุที่เป็นอินสแตนซ์ของคลาส Object
บางครั้งเรียกว่าวัตถุ สัญพจน์ เมื่อสร้างผ่านสัญกรณ์ {}
อ็อบเจ็กต์คลาสเป็นอินสแตนซ์ของคลาสที่มีคอนสตรัคเตอร์ คุณสมบัติ และเมธอดที่กำหนดไว้เอง โดยปกติแล้วคุณจะกำหนดมันผ่านสัญกรณ์ class
แล้วปัญหาคืออะไร?
บางครั้งคุณต้องการแปลงวัตถุจาวาสคริปต์ธรรมดาเป็น คลาส ES6 ที่คุณมี ตัวอย่างเช่น หากคุณกำลังโหลด json จากแบ็กเอนด์ของคุณ api บางส่วนหรือจากไฟล์ json และหลังจากที่คุณ JSON.parse
แล้ว คุณจะมีออบเจ็กต์ javascript ธรรมดา ไม่ใช่อินสแตนซ์ของคลาสที่คุณมี
ตัวอย่างเช่น คุณมีรายชื่อผู้ใช้ใน users.json
ที่คุณกำลังโหลด:
[
{
"id" : 1 ,
"firstName" : " Johny " ,
"lastName" : " Cage " ,
"age" : 27
},
{
"id" : 2 ,
"firstName" : " Ismoil " ,
"lastName" : " Somoni " ,
"age" : 50
},
{
"id" : 3 ,
"firstName" : " Luke " ,
"lastName" : " Dacascos " ,
"age" : 12
}
]
และคุณมีคลาส User
:
export class User {
id : number ;
firstName : string ;
lastName : string ;
age : number ;
getName ( ) {
return this . firstName + ' ' + this . lastName ;
}
isAdult ( ) {
return this . age > 36 && this . age < 60 ;
}
}
คุณกำลังสมมติว่าคุณกำลังดาวน์โหลดผู้ใช้ประเภท User
จากไฟล์ users.json
และอาจต้องการเขียนโค้ดต่อไปนี้:
fetch ( 'users.json' ) . then ( ( users : User [ ] ) => {
// you can use users here, and type hinting also will be available to you,
// but users are not actually instances of User class
// this means that you can't use methods of User class
} ) ;
ในรหัสนี้คุณสามารถใช้ users[0].id
คุณยังสามารถใช้ users[0].firstName
และ users[0].lastName
ได้ อย่างไรก็ตาม คุณไม่สามารถใช้ users[0].getName()
หรือ users[0].isAdult()
เนื่องจากจริงๆ แล้ว "users" เป็นอาร์เรย์ของวัตถุ javascript ธรรมดา ไม่ใช่อินสแตนซ์ของวัตถุ User คุณโกหกคอมไพเลอร์จริง ๆ เมื่อคุณบอกว่า users: User[]
แล้วต้องทำอย่างไร? จะสร้างอาร์เรย์ users
ของอินสแตนซ์ของวัตถุ User
แทนที่จะเป็นวัตถุ javascript ธรรมดาได้อย่างไร วิธีแก้ไขคือการสร้างอินสแตนซ์ใหม่ของออบเจ็กต์ User และคัดลอกคุณสมบัติทั้งหมดไปยังออบเจ็กต์ใหม่ด้วยตนเอง แต่สิ่งต่างๆ อาจผิดพลาดอย่างรวดเร็วเมื่อคุณมีลำดับชั้นของวัตถุที่ซับซ้อนมากขึ้น
ทางเลือก? ใช่ คุณสามารถใช้ class-transformer ได้ วัตถุประสงค์ของไลบรารีนี้คือเพื่อช่วยคุณแมปออบเจ็กต์จาวาสคริปต์ธรรมดาของคุณกับอินสแตนซ์ของคลาสที่คุณมี
ไลบรารีนี้ยังเหมาะสำหรับโมเดลที่เปิดเผยใน API ของคุณ เนื่องจากมีเครื่องมือที่ยอดเยี่ยมในการควบคุมสิ่งที่โมเดลของคุณเปิดเผยใน API ของคุณ นี่คือตัวอย่างว่าจะมีลักษณะอย่างไร:
fetch ( 'users.json' ) . then ( ( users : Object [ ] ) => {
const realUsers = plainToInstance ( User , users ) ;
// now each user in realUsers is an instance of User class
} ) ;
ตอนนี้คุณสามารถใช้เมธอด users[0].getName()
และ users[0].isAdult()
ได้แล้ว
ติดตั้งโมดูล:
npm install class-transformer --save
จำเป็นต้องใช้ shim reflect-metadata
ติดตั้งด้วย:
npm install reflect-metadata --save
และอย่าลืมนำเข้ามันจากทั่วโลก เช่น app.ts:
import 'reflect-metadata' ;
มีการใช้ฟีเจอร์ ES6 หากคุณใช้ node.js เวอร์ชันเก่า คุณอาจต้องติดตั้ง es6-shim:
npm install es6-shim --save
และนำเข้าในที่ระดับโลกเช่น app.ts:
import 'es6-shim' ;
ติดตั้งโมดูล:
npm install class-transformer --save
จำเป็นต้องใช้ shim reflect-metadata
ติดตั้งด้วย:
npm install reflect-metadata --save
เพิ่ม <script>
เพื่อสะท้อนข้อมูลเมตาในส่วนหัวของ index.html
ของคุณ :
< html >
< head >
<!-- ... -->
< script src =" node_modules/reflect-metadata/Reflect.js " > </ script >
</ head >
<!-- ... -->
</ html >
หากคุณใช้เชิงมุม 2 คุณควรติดตั้งแผ่นรองนี้ไว้แล้ว
หากคุณใช้ system.js คุณอาจต้องการเพิ่มสิ่งนี้ลงใน map
และการกำหนดค่า package
:
{
"map" : {
"class-transformer" : " node_modules/class-transformer "
},
"packages" : {
"class-transformer" : { "main" : " index.js " , "defaultExtension" : " js " }
}
}
วิธีการนี้แปลงวัตถุจาวาสคริปต์ธรรมดาให้เป็นอินสแตนซ์ของคลาสเฉพาะ
import { plainToInstance } from 'class-transformer' ;
let users = plainToInstance ( User , userJson ) ; // to convert user plain object a single user. also supports arrays
วิธีนี้จะแปลงวัตถุธรรมดาให้เป็นอินสแตนซ์โดยใช้วัตถุที่เติมไว้แล้วซึ่งเป็นอินสแตนซ์ของคลาสเป้าหมาย
const defaultUser = new User ( ) ;
defaultUser . role = 'user' ;
let mixedUser = plainToClassFromExist ( defaultUser , user ) ; // mixed user should have the value role = user when no value is set otherwise.
วิธีนี้จะแปลงวัตถุคลาสของคุณกลับไปเป็นวัตถุจาวาสคริปต์ธรรมดาซึ่งสามารถเป็น JSON.stringify
ได้ในภายหลัง
import { instanceToPlain } from 'class-transformer' ;
let photo = instanceToPlain ( photo ) ;
วิธีการนี้แปลงวัตถุคลาสของคุณให้เป็นอินสแตนซ์ใหม่ของวัตถุคลาส นี่อาจถือเป็นการโคลนวัตถุระดับลึก
import { instanceToInstance } from 'class-transformer' ;
let photo = instanceToInstance ( photo ) ;
คุณยังสามารถใช้ตัวเลือก ignoreDecorators
ในตัวเลือกการแปลงเพื่อละเว้นการตกแต่งทั้งหมดที่คลาสของคุณใช้อยู่
คุณสามารถซีเรียลไลซ์โมเดลของคุณให้เป็น json ได้โดยตรงโดยใช้วิธี serialize
:
import { serialize } from 'class-transformer' ;
let photo = serialize ( photo ) ;
serialize
ทำงานได้กับทั้งอาร์เรย์และไม่ใช่อาร์เรย์
คุณสามารถดีซีเรียลไลซ์โมเดลของคุณจาก json ได้โดยใช้วิธี deserialize
:
import { deserialize } from 'class-transformer' ;
let photo = deserialize ( Photo , photo ) ;
เพื่อให้การดีซีเรียลไลซ์ทำงานกับอาร์เรย์ได้ ให้ใช้เมธอด deserializeArray
:
import { deserializeArray } from 'class-transformer' ;
let photos = deserializeArray ( Photo , photos ) ;
ลักษณะการทำงานเริ่มต้นของเมธอด plainToInstance
คือการตั้งค่าคุณสมบัติ ทั้งหมด จากวัตถุธรรมดา แม้ว่าจะไม่ได้ระบุไว้ในคลาสก็ตาม
import { plainToInstance } from 'class-transformer' ;
class User {
id : number ;
firstName : string ;
lastName : string ;
}
const fromPlainUser = {
unkownProp : 'hello there' ,
firstName : 'Umed' ,
lastName : 'Khudoiberdiev' ,
} ;
console . log ( plainToInstance ( User , fromPlainUser ) ) ;
// User {
// unkownProp: 'hello there',
// firstName: 'Umed',
// lastName: 'Khudoiberdiev',
// }
หากลักษณะการทำงานนี้ไม่เหมาะกับความต้องการของคุณ คุณสามารถใช้ตัวเลือก excludeExtraneousValues
ในเมธอด plainToInstance
ในขณะที่ เปิดเผยคุณสมบัติคลาสทั้งหมดของคุณ ตามความต้องการ
import { Expose , plainToInstance } from 'class-transformer' ;
class User {
@ Expose ( ) id : number ;
@ Expose ( ) firstName : string ;
@ Expose ( ) lastName : string ;
}
const fromPlainUser = {
unkownProp : 'hello there' ,
firstName : 'Umed' ,
lastName : 'Khudoiberdiev' ,
} ;
console . log ( plainToInstance ( User , fromPlainUser , { excludeExtraneousValues : true } ) ) ;
// User {
// id: undefined,
// firstName: 'Umed',
// lastName: 'Khudoiberdiev'
// }
เมื่อคุณพยายามแปลงวัตถุที่มีวัตถุซ้อนกัน จำเป็นต้องทราบว่าคุณกำลังพยายามแปลงประเภทใด เนื่องจาก Typescript ยังไม่มีความสามารถในการสะท้อนที่ดี เราจึงควรระบุประเภทของวัตถุที่แต่ละคุณสมบัติมีอยู่โดยปริยาย ทำได้โดยใช้ @Type
มัณฑนากร
สมมติว่าเรามีอัลบั้มพร้อมรูปถ่าย และเรากำลังพยายามแปลงวัตถุธรรมดาของอัลบั้มเป็นวัตถุคลาส:
import { Type , plainToInstance } from 'class-transformer' ;
export class Album {
id : number ;
name : string ;
@ Type ( ( ) => Photo )
photos : Photo [ ] ;
}
export class Photo {
id : number ;
filename : string ;
}
let album = plainToInstance ( Album , albumJson ) ;
// now album is Album object with Photo objects inside
ในกรณีที่อ็อบเจ็กต์ที่ซ้อนกันสามารถเป็นประเภทที่แตกต่างกัน คุณสามารถจัดเตรียมออบเจ็กต์ตัวเลือกเพิ่มเติม ที่ระบุตัวแบ่งแยก ตัวเลือก discriminator ต้องกำหนด property
ที่เก็บชื่อประเภทย่อยสำหรับออบเจ็กต์และ subTypes
ที่เป็นไปได้ที่ออบเจ็กต์ที่ซ้อนกันสามารถแปลงเป็นได้ ประเภทย่อยมี value
ซึ่งเก็บ Constructor ของ Type และ name
ซึ่งสามารถจับคู่กับ property
ของ discriminator
สมมติว่าเรามีอัลบั้มที่มีรูปถ่ายยอดนิยม แต่รูปภาพนี้อาจมีหลายประเภท และเรากำลังพยายามแปลงวัตถุธรรมดาของอัลบั้มเป็นวัตถุคลาส อินพุตวัตถุธรรมดาจะต้องกำหนดคุณสมบัติเพิ่มเติม __type
คุณสมบัตินี้จะถูกลบออกระหว่างการแปลงโดยค่าเริ่มต้น:
อินพุต JSON :
{
"id" : 1 ,
"name" : " foo " ,
"topPhoto" : {
"id" : 9 ,
"filename" : " cool_wale.jpg " ,
"depth" : 1245 ,
"__type" : " underwater "
}
}
import { Type , plainToInstance } from 'class-transformer' ;
export abstract class Photo {
id : number ;
filename : string ;
}
export class Landscape extends Photo {
panorama : boolean ;
}
export class Portrait extends Photo {
person : Person ;
}
export class UnderWater extends Photo {
depth : number ;
}
export class Album {
id : number ;
name : string ;
@ Type ( ( ) => Photo , {
discriminator : {
property : '__type' ,
subTypes : [
{ value : Landscape , name : 'landscape' } ,
{ value : Portrait , name : 'portrait' } ,
{ value : UnderWater , name : 'underwater' } ,
] ,
} ,
} )
topPhoto : Landscape | Portrait | UnderWater ;
}
let album = plainToInstance ( Album , albumJson ) ;
// now album is Album object with a UnderWater object without `__type` property.
คำแนะนำ: เช่นเดียวกับอาร์เรย์ที่มีประเภทย่อยต่างกัน นอกจากนี้ คุณยังสามารถระบุ keepDiscriminatorProperty: true
ในตัวเลือกเพื่อเก็บคุณสมบัติ discriminator ไว้ในคลาสผลลัพธ์ของคุณด้วย
คุณสามารถเปิดเผยสิ่งที่ getter หรือเมธอดของคุณส่งคืนได้โดยการตั้งค่า @Expose()
มัณฑนากรให้กับ getters หรือเมธอดเหล่านั้น:
import { Expose } from 'class-transformer' ;
export class User {
id : number ;
firstName : string ;
lastName : string ;
password : string ;
@ Expose ( )
get name ( ) {
return this . firstName + ' ' + this . lastName ;
}
@ Expose ( )
getFullName ( ) {
return this . firstName + ' ' + this . lastName ;
}
}
หากคุณต้องการเปิดเผยคุณสมบัติบางส่วนด้วยชื่ออื่น คุณสามารถทำได้โดยระบุตัวเลือก name
ให้กับ @Expose
มัณฑนากร:
import { Expose } from 'class-transformer' ;
export class User {
@ Expose ( { name : 'uid' } )
id : number ;
firstName : string ;
lastName : string ;
@ Expose ( { name : 'secretKey' } )
password : string ;
@ Expose ( { name : 'fullName' } )
getFullName ( ) {
return this . firstName + ' ' + this . lastName ;
}
}
บางครั้งคุณต้องการข้ามคุณสมบัติบางอย่างระหว่างการแปลง ซึ่งสามารถทำได้โดยใช้ @Exclude
มัณฑนากร:
import { Exclude } from 'class-transformer' ;
export class User {
id : number ;
email : string ;
@ Exclude ( )
password : string ;
}
ตอนนี้เมื่อคุณแปลงผู้ใช้ คุณสมบัติ password
จะถูกข้ามและไม่รวมอยู่ในผลลัพธ์ที่แปลง
คุณสามารถควบคุมการดำเนินการที่คุณจะยกเว้นพร็อพเพอร์ตี้ได้ ใช้ตัวเลือก toClassOnly
หรือ toPlainOnly
:
import { Exclude } from 'class-transformer' ;
export class User {
id : number ;
email : string ;
@ Exclude ( { toPlainOnly : true } )
password : string ;
}
ตอนนี้คุณสมบัติ password
จะถูกแยกออกระหว่างการดำเนินการ instanceToPlain
เท่านั้น ในทางกลับกัน ให้ใช้ตัวเลือก toClassOnly
คุณสามารถข้ามคุณสมบัติทั้งหมดของคลาส และเปิดเผยเฉพาะคุณสมบัติที่จำเป็นอย่างชัดเจน:
import { Exclude , Expose } from 'class-transformer' ;
@ Exclude ( )
export class User {
@ Expose ( )
id : number ;
@ Expose ( )
email : string ;
password : string ;
}
ตอนนี้ id
และ email
จะถูกเปิดเผย และรหัสผ่านจะถูกแยกออกระหว่างการแปลง หรือคุณสามารถตั้งค่ากลยุทธ์การยกเว้นระหว่างการเปลี่ยนแปลงได้:
import { instanceToPlain } from 'class-transformer' ;
let photo = instanceToPlain ( photo , { strategy : 'excludeAll' } ) ;
ในกรณีนี้คุณไม่จำเป็นต้อง @Exclude()
ทั้งชั้นเรียน
หากคุณตั้งชื่อคุณสมบัติส่วนตัวของคุณด้วยคำนำหน้า เช่น _
คุณก็จะสามารถแยกคุณสมบัติดังกล่าวออกจากการแปลงได้เช่นกัน:
import { instanceToPlain } from 'class-transformer' ;
let photo = instanceToPlain ( photo , { excludePrefixes : [ '_' ] } ) ;
การดำเนินการนี้จะข้ามคุณสมบัติทั้งหมดที่ขึ้นต้นด้วย _
คำนำหน้า คุณสามารถส่งผ่านคำนำหน้าจำนวนเท่าใดก็ได้ และคุณสมบัติทั้งหมดที่ขึ้นต้นด้วยคำนำหน้าเหล่านี้จะถูกละเว้น ตัวอย่างเช่น:
import { Expose , instanceToPlain } from 'class-transformer' ;
export class User {
id : number ;
private _firstName : string ;
private _lastName : string ;
_password : string ;
setName ( firstName : string , lastName : string ) {
this . _firstName = firstName ;
this . _lastName = lastName ;
}
@ Expose ( )
get name ( ) {
return this . _firstName + ' ' + this . _lastName ;
}
}
const user = new User ( ) ;
user . id = 1 ;
user . setName ( 'Johny' , 'Cage' ) ;
user . _password = '123' ;
const plainUser = instanceToPlain ( user , { excludePrefixes : [ '_' ] } ) ;
// here plainUser will be equal to
// { id: 1, name: "Johny Cage" }
คุณสามารถใช้กลุ่มเพื่อควบคุมข้อมูลที่จะเปิดเผยและข้อมูลที่จะไม่เปิดเผย:
import { Exclude , Expose , instanceToPlain } from 'class-transformer' ;
export class User {
id : number ;
name : string ;
@ Expose ( { groups : [ 'user' , 'admin' ] } ) // this means that this data will be exposed only to users and admins
email : string ;
@ Expose ( { groups : [ 'user' ] } ) // this means that this data will be exposed only to users
password : string ;
}
let user1 = instanceToPlain ( user , { groups : [ 'user' ] } ) ; // will contain id, name, email and password
let user2 = instanceToPlain ( user , { groups : [ 'admin' ] } ) ; // will contain id, name and email
หากคุณกำลังสร้าง API ที่มีเวอร์ชันต่างกัน class-transformer มีเครื่องมือที่มีประโยชน์อย่างยิ่งสำหรับสิ่งนั้น คุณสามารถควบคุมคุณสมบัติของโมเดลของคุณที่ควรเปิดเผยหรือแยกออกในเวอร์ชันใด ตัวอย่าง:
import { Exclude , Expose , instanceToPlain } from 'class-transformer' ;
export class User {
id : number ;
name : string ;
@ Expose ( { since : 0.7 , until : 1 } ) // this means that this property will be exposed for version starting from 0.7 until 1
email : string ;
@ Expose ( { since : 2.1 } ) // this means that this property will be exposed for version starting from 2.1
password : string ;
}
let user1 = instanceToPlain ( user , { version : 0.5 } ) ; // will contain id and name
let user2 = instanceToPlain ( user , { version : 0.7 } ) ; // will contain id, name and email
let user3 = instanceToPlain ( user , { version : 1 } ) ; // will contain id and name
let user4 = instanceToPlain ( user , { version : 2 } ) ; // will contain id and name
let user5 = instanceToPlain ( user , { version : 2.1 } ) ; // will contain id, name and password
บางครั้งคุณมีวันที่ในวัตถุจาวาสคริปต์ธรรมดาของคุณที่ได้รับในรูปแบบสตริง และคุณต้องการสร้างวัตถุ Date จาวาสคริปต์จริงจากมัน คุณสามารถทำได้โดยส่งวัตถุ Date ไปที่ @Type
มัณฑนากร:
import { Type } from 'class-transformer' ;
export class User {
id : number ;
email : string ;
password : string ;
@ Type ( ( ) => Date )
registrationDate : Date ;
}
เทคนิคเดียวกันนี้สามารถใช้ได้กับประเภทดั้งเดิม Number
, String
, Boolean
เมื่อคุณต้องการแปลงค่าของคุณเป็นประเภทเหล่านี้
เมื่อคุณใช้อาร์เรย์ คุณต้องระบุประเภทของออบเจ็กต์ที่อาร์เรย์มีอยู่ ประเภทนี้ คุณระบุใน @Type()
มัณฑนากร:
import { Type } from 'class-transformer' ;
export class Photo {
id : number ;
name : string ;
@ Type ( ( ) => Album )
albums : Album [ ] ;
}
คุณยังสามารถใช้ประเภทอาร์เรย์ที่กำหนดเองได้:
import { Type } from 'class-transformer' ;
export class AlbumCollection extends Array < Album > {
// custom array functions ...
}
export class Photo {
id : number ;
name : string ;
@ Type ( ( ) => Album )
albums : AlbumCollection ;
}
ไลบรารีจะจัดการการเปลี่ยนแปลงที่เหมาะสมโดยอัตโนมัติ
Set
คอลเลกชัน ES6 และ Map
จำเป็นต้องมี @Type
มัณฑนากรด้วย:
export class Skill {
name : string ;
}
export class Weapon {
name : string ;
range : number ;
}
export class Player {
name : string ;
@ Type ( ( ) => Skill )
skills : Set < Skill > ;
@ Type ( ( ) => Weapon )
weapons : Map < string , Weapon > ;
}
คุณสามารถดำเนินการแปลงข้อมูลเพิ่มเติมได้โดยใช้ @Transform
decorator ตัวอย่างเช่น คุณต้องการทำให้วัตถุ Date
ของคุณเป็นวัตถุ moment
เมื่อคุณเปลี่ยนวัตถุจากธรรมดาเป็นคลาส:
import { Transform } from 'class-transformer' ;
import * as moment from 'moment' ;
import { Moment } from 'moment' ;
export class Photo {
id : number ;
@ Type ( ( ) => Date )
@ Transform ( ( { value } ) => moment ( value ) , { toClassOnly : true } )
date : Moment ;
}
ตอนนี้เมื่อคุณเรียก plainToInstance
และส่งการแสดงวัตถุ Photo แบบธรรมดา มันจะแปลงค่าวันที่ในวัตถุภาพถ่ายของคุณให้เป็นวันที่ปัจจุบัน @Transform
มัณฑนากรยังรองรับกลุ่มและการกำหนดเวอร์ชันด้วย
มัณฑนากร @Transform
จะได้รับอาร์กิวเมนต์เพิ่มเติมเพื่อให้คุณกำหนดค่าวิธีที่คุณต้องการให้การแปลงเสร็จสิ้น
@ Transform ( ( { value , key , obj , type } ) => value )
การโต้แย้ง | คำอธิบาย |
---|---|
value | มูลค่าทรัพย์สินก่อนการแปลง |
key | ชื่อของทรัพย์สินที่แปลงแล้ว |
obj | วัตถุต้นทางการเปลี่ยนแปลง |
type | ประเภทการเปลี่ยนแปลง |
options | วัตถุตัวเลือกที่ส่งผ่านไปยังวิธีการแปลง |
ลายเซ็น | ตัวอย่าง | คำอธิบาย |
---|---|---|
@TransformClassToPlain | @TransformClassToPlain({ groups: ["user"] }) | แปลงวิธีการส่งคืนด้วย instanceToPlain และเปิดเผยคุณสมบัติในชั้นเรียน |
@TransformClassToClass | @TransformClassToClass({ groups: ["user"] }) | แปลงวิธีการส่งคืนด้วย instanceToInstance และเปิดเผยคุณสมบัติในคลาส |
@TransformPlainToClass | @TransformPlainToClass(User, { groups: ["user"] }) | แปลงวิธีการส่งคืนด้วย plainToInstance และเปิดเผยคุณสมบัติในคลาส |
มัณฑนากรด้านบนยอมรับอาร์กิวเมนต์ทางเลือกหนึ่งรายการ: ClassTransformOptions - ตัวเลือกการแปลง เช่น กลุ่ม เวอร์ชัน ชื่อ
ตัวอย่าง:
@ Exclude ( )
class User {
id : number ;
@ Expose ( )
firstName : string ;
@ Expose ( )
lastName : string ;
@ Expose ( { groups : [ 'user.email' ] } )
email : string ;
password : string ;
}
class UserController {
@ TransformClassToPlain ( { groups : [ 'user.email' ] } )
getUser ( ) {
const user = new User ( ) ;
user . firstName = 'Snir' ;
user . lastName = 'Segal' ;
user . password = 'imnosuperman' ;
return user ;
}
}
const controller = new UserController ( ) ;
const user = controller . getUser ( ) ;
ตัวแปร user
จะมีเฉพาะชื่อ นามสกุล และคุณสมบัติอีเมลเท่านั้น เนื่องจากเป็นตัวแปรที่เปิดเผย คุณสมบัติอีเมลก็ถูกเปิดเผยเช่นกันเนื่องจากเรากล่าวถึงกลุ่ม "user.email"
ไม่รองรับข้อมูลทั่วไปเนื่องจาก TypeScript ยังไม่มีความสามารถในการสะท้อนที่ดี เมื่อทีม TypeScript ให้เครื่องมือสะท้อนประเภทรันไทม์ที่ดีขึ้นแก่เราแล้ว ข้อมูลทั่วไปจะถูกนำมาใช้ มีการปรับแต่งบางอย่างที่คุณสามารถใช้ได้ ซึ่งอาจช่วยแก้ปัญหาของคุณได้ ชำระเงินตัวอย่างนี้
หมายเหตุ หากคุณใช้ class-validator ร่วมกับ class-transformer คุณคงไม่ต้องการเปิดใช้งานฟังก์ชันนี้
เปิดใช้งานการแปลงอัตโนมัติระหว่างประเภทในตัวตามข้อมูลประเภทที่ Typescript ให้ไว้ ปิดใช้งานตามค่าเริ่มต้น
import { IsString } from 'class-validator' ;
class MyPayload {
@ IsString ( )
prop : string ;
}
const result1 = plainToInstance ( MyPayload , { prop : 1234 } , { enableImplicitConversion : true } ) ;
const result2 = plainToInstance ( MyPayload , { prop : 1234 } , { enableImplicitConversion : false } ) ;
/**
* result1 will be `{ prop: "1234" }` - notice how the prop value has been converted to string.
* result2 will be `{ prop: 1234 }` - default behaviour
*/
การอ้างอิงแบบวงกลมจะถูกละเว้น ตัวอย่างเช่น หากคุณกำลังเปลี่ยนคลาส User
ที่มี photos
คุณสมบัติเป็นประเภท Photo
และ Photo
มีลิงก์ user
ไปยัง User
หลัก user
จะถูกละเว้นในระหว่างการแปลง การอ้างอิงแบบวงกลมจะไม่ถูกละเว้นในระหว่างการดำเนินการ instanceToInstance
เท่านั้น
สมมติว่าคุณต้องการดาวน์โหลดผู้ใช้และต้องการให้แมปพวกเขากับอินสแตนซ์ของคลาส User
โดยอัตโนมัติ
import { plainToInstance } from 'class-transformer' ;
this . http
. get ( 'users.json' )
. map ( res => res . json ( ) )
. map ( res => plainToInstance ( User , res as Object [ ] ) )
. subscribe ( users => {
// now "users" is type of User[] and each user has getName() and isAdult() methods available
console . log ( users ) ;
} ) ;
คุณยังสามารถฉีดคลาส ClassTransformer
เป็นบริการใน providers
และใช้วิธีการของมันได้
ตัวอย่างวิธีใช้กับ เชิงมุม 2 ในพลั่วเกอร์ ซอร์สโค้ดอยู่ที่นี่
ดูตัวอย่างใน ./sample เพื่อดูตัวอย่างการใช้งานเพิ่มเติม
ดูข้อมูลเกี่ยวกับการเปลี่ยนแปลงล่าสุดและบันทึกประจำรุ่นได้ที่นี่