2017-12-10 7 views
1

ich eine Klasse Dekorateur und möchte es benutzen einen anderen Dekorateur auf alle Methoden innerhalb der Klasse zu bewerben, aber ich bin mir nicht ganz sicher, wie ein Dekorateur programmatisch ohne die @ Syntax anwenden:js anwenden Dekorateur programmatisch

@LogAllMethods 
class User { 
    greet() { 
     console.log('Hello') 
    } 
} 

function LogAllMethods(target) { 
    for (const key in Object.keys(target.prototype)) { 
     // apply LogMethod decorator 
    } 
} 

function LogMethod(target, key, descriptor) { 
    let method = descriptor.value 
    decriptor.value = function(...args) { 
     console.log(args) 
     method.apply(this, ...args) 
    } 
} 
+0

haben Sie ES5 oder ES2015 Ziel? –

+0

Sie verwenden nicht '@' Syntax, um es programmgesteuert zu tun. Sie überprüfen die Spezifikation für das, was die '@' Syntax tut, dann tun Sie das vom Code. – Bergi

Antwort

0

Sie im Grunde müssen nur die Funktion Dekorateur rufen mit dem Ziel, die Taste (Methodenname) und den definierten Descriptor:

function LogAllMethods<T>(target: new (...params: any[]) => T) { 
    for (const key of Object.getOwnPropertyNames(target.prototype)) { 
     let descriptor = Object.getOwnPropertyDescriptor(target.prototype, key); 
     descriptor = LogMethod(target.prototype, key, descriptor); 
     if (descriptor) { 
      Object.defineProperty(target.prototype, key, descriptor); 
     } 
    } 
} 

function LogMethod(target: any, key: symbol | string, descriptor: TypedPropertyDescriptor<any> = undefined) { 

    if (descriptor) { 
     let method = descriptor.value; 
     if (method instanceof Function) { 
      descriptor.value = function (...args: any[]) { 
       console.log("Log", args) 
       method.apply(this, ...args); 
      } 
     } 
     return descriptor; 
    } else { 
     // descriptor is null for target es5 if the decorator is applied directly to the merhod 
     let method = target[key]; 
     if (method instanceof Function) { 
      target[key] = function (...args: any[]) { 
       console.log("Log", args) 
       method.apply(this, ...args); 
      } 
     } 
    } 
}