Angular 7 - Сервисы с событием / наблюдаемой подпиской в ​​конструкторе и вызовом абстрактного метода - PullRequest
1 голос
/ 24 апреля 2019

Представьте себе следующую ситуацию:

Вы хотели бы реализовать службу Angular, которая должна существовать в двух модах: одна, использующая конечную точку REST, и другая, которая работает как фиктивная, не имея зависимости от конечной точки. Служба REST должна использоваться в производственной среде, а макет - в разработке.

Поскольку у обеих реализаций много общего, они оба выходят из абстрактного класса. Поскольку служба (не имеет значения, какая конкретная реализация) должна вызываться на основе некоторых входящих событий, соответствующая подписка помещается в конструктор абстрактного суперкласса.

abstract class AService {

  constructor(someServiceEmittingEvents) {
      someServiceEmittingEvents.subscribe(() => {
         this.doSomething();
      });
  };

  abstract doSomething(): void;
}

class RestService extends AService {
  constructor(someServiceEmittingEvents, private httpClient: HttpClient) {
    super(someServiceEmittingEvents);
  }

  doSomething(): void {
     this.httpClient.post(...);
  }
}

class MockService extends AService {
  constructor(someServiceEmittingEvents) {
    super(someServiceEmittingEvents);
  }

  doSomething(): void {
    ...
  }
}

Пожалуйста, рассмотрите блок кода как псевдосинтаксис.

Когда предоставляется RestService, время от времени случается, что событие генерируется и обрабатывается, пока сам сервис находится "в разработке". Это приводит к тому, что метод doSomething вызывается в RestService, в то время как HttpClient не был назначен, поэтому он не определен при вызове doSomething.

По крайней мере, так это выглядит, когда регистрируются вызовы конструктора и метода, и это звучит для меня вполне осуществимо.

Поскольку у сервисов Angular нет хуков жизненного цикла, как у компонентов, я бы хотел спросить, каким будет подходящий способ.

1 Ответ

1 голос
/ 24 апреля 2019

Я бы вообще не подписывался на что-либо в конструкторе. Это приводит к подобным ситуациям.

Я бы рекомендовал вам поместить someServiceEmittingEvents.subscribe в отдельный init() метод (или что-то похожее). Вызовите этот метод из методов ngOnInit() ваших компонентов. Таким образом, вы можете быть уверены, что услуга (и ее возможные потребители) были созданы до подписки на наблюдаемое.

Грязная альтернатива - дождаться следующего тика, прежде чем вызвать someServiceEmittingEvents.subscribe (используя что-то вроде setTimeout или setImmediate). Однако это действительно обходной путь, который я бы не рекомендовал.

...