Saya akhirnya bermain-main dengan dekorator dan memutuskan untuk mendokumentasikan apa yang saya temukan bagi siapa saja yang ingin memanfaatkan ini sebelum dokumentasi apa pun keluar. Silakan mengedit ini jika Anda melihat kesalahan.
Poin Umum
- Dekorator dipanggil saat kelas dideklarasikan — bukan saat objek dibuat.
- Beberapa dekorator dapat didefinisikan pada Kelas / Properti / Metode / Parameter yang sama.
- Dekorator tidak diperbolehkan menggunakan konstruktor.
Penghias yang valid harus:
- Ditugaskan ke salah satu jenis Dekorator (
ClassDecorator | PropertyDecorator | MethodDecorator | ParameterDecorator
).
- Kembalikan nilai (dalam hal dekorator kelas dan dekorator metode) yang dapat ditugaskan ke nilai yang didekorasi.
Referensi
Metode / Dekorator Pengakses Formal
Parameter implementasi:
target
: Prototipe kelas ( Object
).
propertyKey
: Nama metode ( string
| symbol
).
descriptor
: A TypedPropertyDescriptor
- Jika Anda tidak terbiasa dengan kunci deskriptor, saya akan merekomendasikan membacanya di dokumentasi ini pada Object.defineProperty
(ini adalah parameter ketiga).
Contoh - Tanpa Argumen
Menggunakan:
class MyClass {
@log
myMethod(arg: string) {
return "Message -- " + arg;
}
}
Penerapan:
function log(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) {
const originalMethod = descriptor.value; // save a reference to the original method
// NOTE: Do not use arrow syntax here. Use a function expression in
// order to use the correct value of `this` in this method (see notes below)
descriptor.value = function(...args: any[]) {
// pre
console.log("The method args are: " + JSON.stringify(args));
// run and store result
const result = originalMethod.apply(this, args);
// post
console.log("The return value is: " + result);
// return the result of the original method (or modify it before returning)
return result;
};
return descriptor;
}
Memasukkan:
new MyClass().myMethod("testing");
Keluaran:
Metode args adalah: ["testing"]
Nilai kembali adalah: Pesan - pengujian
Catatan:
- Jangan gunakan sintaks panah saat mengatur nilai deskriptor. Konteks
this
tidak akan menjadi instance jika Anda melakukannya.
- Lebih baik memodifikasi deskriptor asli daripada menimpa yang sekarang dengan mengembalikan deskriptor baru. Ini memungkinkan Anda untuk menggunakan beberapa dekorator yang mengedit deskriptor tanpa menimpa apa yang dilakukan dekorator lain. Melakukan ini memungkinkan Anda untuk menggunakan sesuatu seperti
@enumerable(false)
dan @log
pada saat yang sama (Contoh: Buruk vs Baik )
- Berguna : Argumen tipe dari
TypedPropertyDescriptor
dapat digunakan untuk membatasi tanda tangan metode apa ( Contoh Metode ) atau tanda tangan accessor ( Contoh Accessor ) dekorator dapat memakai.
Contoh - Dengan Argumen (Pabrik Penghias)
Saat menggunakan argumen, Anda harus mendeklarasikan fungsi dengan parameter dekorator lalu mengembalikan fungsi dengan tanda tangan contoh tanpa argumen.
class MyClass {
@enumerable(false)
get prop() {
return true;
}
}
function enumerable(isEnumerable: boolean) {
return (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => {
descriptor.enumerable = isEnumerable;
return descriptor;
};
}
Dekorator Metode Statis
Mirip dengan dekorator metode dengan beberapa perbedaan:
- Its
target
parameter adalah fungsi konstruktor sendiri dan tidak prototipe.
- Deskriptor didefinisikan pada fungsi konstruktor dan bukan prototipe.
Dekorator Kelas
@isTestable
class MyClass {}
Parameter implementasi:
target
: Kelas dekorator dideklarasikan pada ( TFunction extends Function
).
Contoh penggunaan : Menggunakan api metadata untuk menyimpan informasi di kelas.
Dekorator Properti
class MyClass {
@serialize
name: string;
}
Parameter implementasi:
target
: Prototipe kelas ( Object
).
propertyKey
: Nama properti ( string
| symbol
).
Contoh penggunaan : Membuat @serialize("serializedName")
dekorator dan menambahkan nama properti ke daftar properti untuk diserialisasi.
Dekorator Parameter
class MyClass {
myMethod(@myDecorator myParameter: string) {}
}
Parameter implementasi:
target
: Prototipe kelas ( Function
- sepertinya Function
tidak berfungsi lagi. Anda harus menggunakan any
atau di Object
sini sekarang untuk menggunakan dekorator dalam kelas apa pun. Atau tentukan jenis kelas yang ingin Anda batasi)
propertyKey
: Nama metode ( string
| symbol
).
parameterIndex
: Indeks parameter dalam daftar parameter fungsi ( number
).
Contoh sederhana
Contoh terperinci
@Injectable
ke dekorator, lihat