Стратегия аннулирования подписки на Angular 2 - PullRequest
1 голос
/ 13 марта 2019

У меня проблема с подписками при использовании собственного декоратора для обновления некоторых данных.

Ситуация такая: У меня есть кастом декоратор UserChange. Этот декоратор является декоратором метода и в нескольких компонентах используется для запуска метода компонента при изменении пользователя.
Декоратор подписывается на поток пользователя и всякий раз, когда пользователь меняет его, вызывает метод:

Пример:

декоратор:

export function UserChange(updater: UserUpdater) {
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    descriptor.value = function () {
      const update = updater.userChanges().subscribe(() => {
        // @ts-ignore
        return originalMethod.apply(this, arguments);
      });
      return originalMethod.apply(this, arguments);
    };
    return descriptor;
  };
}

пример использования в некоторых компонентах:

@UserChange(AppModule.userUpdater)
private loadUserData() {
    this.api.getUserData.subscribe(...);
}

Проблема в том, как отписать userChanges.subscription() в декораторе, когда компонент уничтожен?

Обычно подписка отменяется в ngOnDestroy компонента, но в этом месте я не имею никакого влияния на подписку декоратора. Та же ситуация в противоположном направлении. У меня нет ссылки на компонент subscription для вызова add(update) по этому вопросу. Поскольку target является прототипом класса, а не фактическим экземпляром класса компонента.

Как решить эту проблему? Как отписаться от подписки декоратора?

1 Ответ

0 голосов
/ 13 марта 2019

Ну, я наконец-то нашел решение:

export function UserChange(updater: UserUpdater) {
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    descriptor.value = function () {
      const update = updater.userChanges().subscribe(() => {
        // @ts-ignore
        return originalMethod.apply(this, arguments);
      });

      target['ngOnDestroy'] = () => update.unsubscribe();

      return originalMethod.apply(this, arguments);
    };
    return descriptor;
  };
}
...