Búsqueda de sitios web

typescript - Angular 4 Decorador no puede acceder al ámbito de la clase


Estoy tratando de escribir un decorador que llame a un método después de un intervalo determinado. La idea es crear un servicio de datos en tiempo real sin cambiar nada en el código del servicio base.

Hasta ahora he podido lograr lo siguiente:

Código de decorador:

export const ON_DESTROY_SYMBOL = Symbol();

export function repeat(): MethodDecorator {
    return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        // get the original method reference
        const originalMethod = descriptor.value;
        let timer;
        descriptor.value = (...args) => {
        //set a timer to call the method every 3 seconds
        //TODO: make the interval dynamic
            timer = setInterval( () =>  {
                originalMethod.apply(target, args);
            }, 3000);
        };
        target[ON_DESTROY_SYMBOL] = target.ngOnDestroy;
        // Destroy timer on Component destroy
        target.ngOnDestroy = function () {
            this[ON_DESTROY_SYMBOL]();
            clearInterval(timer);
            console.log('Component destroy event successfully handled!');
        };
        return descriptor;
    };
}

Y úsalo así:

@repeat()
myMethod() {
    console.log('Logging in console',new Date());
}

Esto funciona como se esperaba. El método se repite cada 3 segundos y puedo ver los registros en la consola.

Pero cuando intento usar cualquier servicio en la clase, falla con un error

Cannot read property 'someService' of undefined

Mi objetivo es poder usarlo así,

Código del componente:

export class PlaygroundComponent implements OnInit, OnDestroy {
    //inject service
    constructor(private someService: SomeService){
    }

    @repeat()
    myMethod() {
        this.someService.fetchData().subscribe(res => //do something with data);
    }
}

Código de servicio:

@Injectable()
export class SomeService {
constructor(private http: HttpClient) {
}

fetchData() {
    return this.http.get('https://data.com/json/')
}

No puedo averiguar cómo usar el alcance correcto en el decorador. Se agradecen cualquier pista.

Respuesta #1

target.ngOnDestroy = function () {

debería ser

target.ngOnDestroy = () => {