Как установить объект this в функции обратного вызова для компонента контейнера из декоратора класса - PullRequest
0 голосов
/ 12 февраля 2019

Привет! Я пытаюсь создать декоратор класса для своих серверных сервисов, чтобы я мог с легкостью делиться своими сервисами с любым компонентом. У меня есть функция onUser, которая действует как обратный вызов, когда я получаю пользовательские данные.с сервера, но попытка доступа «this» к callbach, который я вызываю на декораторе, показывает, что «this» отличается от «this» компонента контейнера. Что мне не хватает?спасибо

класс декоратора

export function UserSubscriber() {
  return (constructor: any) => {
    const component = constructor.name;

    const userService: UserClientService = 
               InjectorInstance.get<UserClientService>(UserClientService);

    let subscription: Subscription;

    subscription = userService.user$.subscribe(function(user) {
      constructor.prototype.onUser(user);
    });

    const orgOnInit = constructor.prototype['ngOnInit'];
    constructor.prototype['ngOnInit'] = function (...args) {
      if (orgOnInit) {
        orgOnInit.apply(this, args);
      }
    };

    const orgOnDestroy = constructor.prototype['ngOnDestroy'];
    constructor.prototype['ngOnDestroy'] = function(...args) {
      subscription.unsubscribe();
      if (orgOnDestroy) {
        orgOnDestroy.apply(this, args);
      }
    };
  };
}

контейнер компонента / вызываемого абонента)

@UserSubscriber()
@Component({
 ...
})
export class AppComponent {
  ...

  onUser(user) {
    console.log(user);

    console.log(this); // this is not the instance of this component
  }
}

1 Ответ

0 голосов
/ 12 февраля 2019

Переместите подписку в переопределение ngOnInit и используйте там функцию стрелки:

constructor.prototype['ngOnInit'] = function (...args) {
  subscription = userService.user$.subscribe(user => { // preserve this
    constructor.prototype.onUser.call(this, user); // call with component context
  });
  if (orgOnInit) {
    orgOnInit.apply(this, args);
  }
};

Также уничтожьте подписку, если она инициализирована в хуке ngOnDestroy:

constructor.prototype['ngOnDestroy'] = function(...args) {
  if (subscription) {
    subscription.unsubscribe();
  }

  ...
};
...