2016-01-13 18 views
12

How to implement a typescript decorator? è un buon esempio di come utilizzare decorator in dattiloscritto.Come passare una variabile di istanza in argomenti decoratore dattiloscritto?

Considerando il caso sotto,

class MyClass { 
    @enumerable(false) 
    get prop() { 
     return true; 
    } 

    @property({required: true}) //here pass constant is no issue 
    public startDateString:string; 

    @property({afterDate: this.startDateString}) //how to pass startDateString here? 
    public endDateString:string; 
} 

function enumerable(isEnumerable: boolean) { 
    return (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => { 
     descriptor.enumerable = isEnumerable; 
     return descriptor; 
    }; 
} 

ho provato tutto ma sembra non ho modo di passare startDateString in argomento decoratore. startDateString potrebbe essere una variabile, una funzione e un riferimento.

+0

Questo potrebbe essere possibile a seconda di _how_ e _quando_ è necessario utilizzare il valore passato. Capisco che devi passare il ... errrr ... _istanza value_ di 'startDateString' al decoratore applicato a' endDateString', ma cosa hai intenzione di _do_ con esso nel decoratore? A seconda delle circostanze, è possibile ottenere un membro di istanza tramite un decoratore. –

risposta

6

Quello che stai cercando di fare non è possibile.

I decoratori vengono chiamati quando la classe viene dichiarata e in questo momento non c'è alcuna istanza da passare nel decoratore.

Ad esempio, con questo codice:

class MyClass { 
    startDateString: string; 
    @property({ afterDate: this.startDateString }) 
    endDateString: string; 
} 
let myClass = new MyClass(); 
  1. MyClass è dichiarato.
  2. I decoratori sono gestiti su MyClass. Non esiste un'istanza che esiste per passare a questo punto e this nell'argomento decoratore si riferisce all'oggetto globale, non a un'istanza.
  3. new MyClass() viene chiamato e l'istanza viene creata. I decoratori non sono chiamati su questo passaggio. E 'già successo.

Date un'occhiata al JavaScript compilato per riferimento:

var MyClass = (function() { 
    // -- 1 -- 
    function MyClass() { 
    } 
    // -- 2 -- 
    __decorate([ 
     // see here... `this` is equal to the global object 
     property({ afterDate: this.startDateString }) 
    ], MyClass.prototype, "endDateString", void 0); 
    return MyClass; 
})(); 
// -- 3 -- 
var myClass = new MyClass(); 

noti che usare this.startDateString non genera un errore di compilazione qui perché this è tipizzato come any.

Quindi, cosa sta cercando di fare qui passando una proprietà di istanza non ha senso e non è possibile.

Quello che si potrebbe fare è rendere statico startDateString quindi passarlo in questo modo: @property({ afterDate: MyClass.startDateString }).

+0

Grazie. Ma nel mio caso, non può essere statico essere una variabile di classe. Deve essere una variabile di istanza. – new2cpp

+0

@ new2cpp Una cosa che si può fare è passare una stringa o una funzione che viene passata un'istanza della classe e restituisce il valore della proprietà. Qualcosa come '{afterDate:" startDateString "}' o '{afterDate: (instance: MyClass) => instance.startDate}'. È quindi possibile utilizzare queste informazioni in un secondo momento una volta che si dispone di un'istanza della classe per ottenere il valore dalla proprietà. È una soluzione hacky che è un ottimo modo per confondere tutti guardando il codice però. –

3

Non è possibile accedere a una proprietà dell'oggetto da una definizione di attributo.

Decoratore viene chiamato quando la proprietà è definita.

È possibile utilizzare getter o setter per ottenere il controllo quando si accede alla proprietà.

Problemi correlati