Dekoratörler ile oynamaya son verdim ve herhangi bir belge çıkmadan önce bundan yararlanmak isteyen herkes için neyi anladığımı belgelemeye karar verdim. Herhangi bir hata görürseniz lütfen bunu düzenlemekten çekinmeyin.
Genel Hususlar
- Dekoratörler, bir nesne başlatıldığında değil, sınıf bildirildiğinde çağrılır.
- Aynı Sınıf / Özellik / Yöntem / Parametre üzerinde birden fazla dekoratör tanımlanabilir.
- Dekoratörlere yapıcılara izin verilmez.
Geçerli bir dekoratör şöyle olmalıdır:
- Dekoratör türlerinden birine atanabilir (
ClassDecorator | PropertyDecorator | MethodDecorator | ParameterDecorator
).
- Dekore edilmiş değere atanabilir bir değer (sınıf dekoratörleri ve yöntem dekoratörü olması durumunda) döndürün.
Referans
Yöntem / Formal Accessor Dekoratör
Uygulama parametreleri:
target
: ( Object
) Sınıfının prototipi .
propertyKey
: Yöntemin adı ( string
| symbol
).
descriptor
A TypedPropertyDescriptor
- Bir açıklayıcısı anahtarIarýyIa bilginiz yoksa, ben bu konuda okumanızı tavsiye ederim bu belgelerin üzerinde Object.defineProperty
(üçüncü parametre var).
Örnek - Bağımsız Değişken Olmadan
kullanın:
class MyClass {
@log
myMethod(arg: string) {
return "Message -- " + arg;
}
}
Uygulama:
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;
}
Giriş:
new MyClass().myMethod("testing");
Çıktı:
Yöntem argümanları: ["test"]
Dönüş değeri: Mesaj - test
Notlar:
- Tanımlayıcının değerini ayarlarken ok sözdizimini kullanmayın. Eğer yaparsanız, içeriği bağlam
this
olmayacaktır.
- Orijinal tanımlayıcıyı değiştirmek, yeni bir tanımlayıcı döndürerek geçerli olanın üzerine yazmaktan daha iyidir. Bu, başka bir dekoratörün yaptıklarının üzerine yazmadan tanımlayıcıyı düzenleyen birden fazla dekoratör kullanmanıza izin verir. Bunu yapmak , aynı anda
@enumerable(false)
ve benzeri bir şey kullanmanıza izin verir @log
(Örnek: Kötü vs İyi )
- Yararlı : Dekoratörünün tür argümanı , dekoratörün
TypedPropertyDescriptor
hangi yöntem imzalarını ( Yöntem Örneği ) veya erişimci imzalarını ( Erişimci Örneği ) koyabileceğini kısıtlamak için kullanılabilir .
Örnek - Bağımsız Değişkenlerle (Dekoratör Fabrikası)
Bağımsız değişkenleri kullanırken, dekoratör parametreleriyle bir işlev bildirmeniz ve ardından bağımsız değişken olmadan örneğin imzasını içeren bir işlev döndürmeniz gerekir.
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;
};
}
Statik Yöntem Dekoratörü
Bazı farklılıkları olan bir yöntem dekoratörüne benzer:
- Onun
target
parametre yapıcı işlevi kendisi değil prototipidir.
- Tanımlayıcı, prototipte değil yapıcı işlevinde tanımlanır.
Sınıf Dekoratörü
@isTestable
class MyClass {}
Uygulama parametresi:
target
: Dekoratörün bildirildiği sınıf ( TFunction extends Function
).
Örnek kullanım : Bir sınıfta bilgi depolamak için meta veri api'sini kullanma.
Emlak Dekoratörü
class MyClass {
@serialize
name: string;
}
Uygulama parametreleri:
target
: ( Object
) Sınıfının prototipi .
propertyKey
: Özelliğin adı ( string
| symbol
).
Örnek kullanım : Bir @serialize("serializedName")
dekoratör oluşturma ve özellik adını serileştirilecek özellikler listesine ekleme.
Parametre Dekoratörü
class MyClass {
myMethod(@myDecorator myParameter: string) {}
}
Uygulama parametreleri:
target
: Sınıfın prototipi ( Function
— Function
artık görünmüyor. Dekoratörü herhangi bir sınıfta kullanmak için şimdi any
veya Object
burada kullanmalısınız. Veya kısıtlamak istediğiniz sınıf türlerini belirtin)
propertyKey
: Yöntemin adı ( string
| symbol
).
parameterIndex
: İşlevin parametreleri listesindeki parametre dizini ( number
).
Basit örnek
Ayrıntılı Örnek (ler)
@Injectable
Bir dekoratöre enjekte etmek istiyorsanız , bakın