2017-02-16 31 views
5

Tipcript'te, sınıf için meta verileri ayarlamak üzere bir özellik dekoratörünün kullanılması mümkün müdür? Aşağıdaki kodu dikkate alın. Sınıf dekoratörünün "hedefi", görünüşte, özellik dekoratörünün "hedefi" ile aynı değildir. Birini diğerinden çıkarabilir miyim?typescript özellikli dekoratörler sınıf için meta veriler ayarlayabilir mi?

import 'reflect-metadata'; 


const MY_CLASS_DECORATOR_KEY = 'MyClassDecoratorKey'; 
const MY_PROPERTY_DECORATOR_KEY = 'MyPropertyDecoratorKey'; 

export const MyClassDecorator = options => { 
    return function (target) { 
     console.log('class target: ' , target); 
     Reflect.defineMetadata(MY_CLASS_DECORATOR_KEY, options, target); 
    }; 
}; 

export const MyPropertyDecorator = (options): PropertyDecorator => { 
    return (target, property) => { 
     console.log('property target: ' , target); 
     const metadata = Reflect.getMetadata(MY_PROPERTY_DECORATOR_KEY, target) || {}; 
     metadata[property] = options; 
     Reflect.defineMetadata(MY_PROPERTY_DECORATOR_KEY, metadata, target); 
    }; 
}; 

@MyClassDecorator('my class decorator value') 
class MyClass { 
    @MyPropertyDecorator('first my property decorator value') 
    myFirstProperty: any; 

    @MyPropertyDecorator('second my property decorator value') 
    mySecondProperty: any; 
} 

console.log('keys: ', Reflect.getMetadataKeys(MyClass)); 

Not çıkışı:

property target: MyClass {} 
property target: MyClass {} 
class target: function MyClass() { 
    } 
keys: [ 'MyClassDecoratorKey' ] 

nasıl da mülkiyet dekoratör anahtarları göstermek için meta veri anahtarlarını alabilirim?

cevap

3

Evet, dekoratörünüzde istediğiniz her şeyi yapmakta özgürsünüz, ancak öğrendiğiniz gibi, sorunlarınız geçirilmekte olduğunuz hedefle ilgilidir.

Temel olarak bir özellik dekoratör içinde, target parametre dekoratör statik özellik veya bir örnek özelliği kullanılır bağlı olarak iki şeyden biri olabilir:

statik özellik üzerinde target malı olacak sınıf kurucu işlevi. Bu, statik bir özellikte hedefin, sınıf dekoratörünüz için olduğu gibi aynı olacağı anlamına gelir.

Ancak, bir örnek özelliğinde target parametresi oluşturduğunuz sınıfın oluşturucusu değil, prototype olacaktır. Bu yüzden gördüğünüz davranışı görüyorsunuz. Örnek özelliği söz konusu olduğunda, meta verileriniz sınıf dekoratörünüzde olduğu gibi constructor'a eklenmez.

Yine de umut var, çünkü constructor adında bir özellikte depolanan bir prototip örneğini verdiğiniz kurucu işlevine kolayca ulaşabilirsiniz.

export const MyPropertyDecorator = (options): PropertyDecorator => { 
    return (target, property) => { 
     var classConstructor = target.constructor; 
     console.log('property target: ' , classConstructor); 
     const metadata = Reflect.getMetadata(MY_PROPERTY_DECORATOR_KEY, classConstructor) || {}; 
     metadata[property] = options; 
     Reflect.defineMetadata(MY_PROPERTY_DECORATOR_KEY, metadata, classConstructor); 
    }; 
}; 

NOT: sizin durumda Yani, bunu yaparak aradığınız davranışı elde edebilirsiniz Yukarıdaki değişim statik özelliklere örnek özellikleri için çalışır, ancak olmazdı. Her iki özellik türünü de kullanmanız gerekiyorsa, target veya target.constructor

+0

Ah'in kullanılmamasını belirlemek için ek bir mantık eklemeniz gerekir. Cevabınız tam ihtiyacım olan şey. Çok teşekkürler! Ama sanırım diğer yöne gitmek ve meta vereni yapıcı yerine prototip üzerine koymak istedim? Diğer yöne gidebilir miyim? – bkinsey808

+0

Elbette, sadece target.prototype yapın – dtabuenc

İlgili konular