Angular 7: пользовательский декоратор класса уничтожает область видимости компонента - PullRequest
0 голосов
/ 25 октября 2018

У меня есть декоратор, который на ngOnInit пишет console.log

log.decorator.ts

export function Log(): ClassDecorator {

    // Decorator Factory
    return (target: Function) => {

        const ngOnInit: Function = target.prototype.ngOnInit;
        target.prototype.ngOnInit = ( ...args ) => {

            console.log('ngOnInit:', target.name);

            if ( ngOnInit ) {
                ngOnInit.apply(this, args);
            }
        };
    };
}

и HelloComponent, которые используют@Log() и импортируйте службу, используемую в ngOnInit

hello.component.ts

import { Component, Input, OnInit } from '@angular/core';
import { Log } from './log.decorator';
import { HelloService } from './hello.service';

@Component({
  selector: 'hello',
  template: `<p>Hello! thanks for help and open the browser console for see the error!</p>`,
  styles: [``]
})
// if you remove @Log(), helloService.sayHello() works!
@Log()
export class HelloComponent implements OnInit  {

  constructor(private helloService: HelloService){}

  ngOnInit(){
    this.helloService.sayHello();
  }
}

, но это вызывает исключение:

ОШИБКА TypeError: Невозможно прочитать свойство 'sayHello' из неопределенного

, если я удаляю @Log() из HelloComponent, это работает!

кажется, что декоратор разрушает область компонента:

ngOnInit.apply(this, args); // line 13: log.decorator.ts

после этого вызова this.helloService равно undefined в ngOnInit из HelloComponent, но без @Log(), this.helloService - это HelloService экземпляр.

Как это исправить?

Живой пример на Stackblitz: https://stackblitz.com/edit/angular-7hhp5n

1 Ответ

0 голосов
/ 25 октября 2018

Функция стрелки заставляет контекст this быть включающим лексический контекст и контекст выполнения функции Log.

Чтобы иметь контекст компонента, вы должны использовать простое выражение функции:

target.prototype.ngOnInit = function( ...args ) {
   ...
}

Разветвленный стек-блиц

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...