想象一下以下情况:
您希望实现一个应该以两种方式存在的Angular服务:一种使用REST端点,另一种用作模拟,而不依赖于端点。在开发中使用mock时,应在生产环境中使用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时,它会不时地发生并在服务本身处于“构造中”时处理事件。这导致在RestService中调用方法doSomething
,而未分配HttpClient,因此在调用doSomething
时未定义。
至少这是记录构造函数和方法调用时的样子,这听起来对我来说是可行的。
由于Angular服务没有生命周期钩子作为组件,我想问一下适当的方式。
我通常会避免订阅构造函数中的任何内容。它往往导致这样的情况。
我建议你将你的someServiceEmittingEvents.subscribe
放入一个单独的init()
方法(或类似的东西)。从组件的ngOnInit()
方法中调用该方法。像这样,您可以确保在订阅observable之前已经构建了服务(及其可能的使用者)。
脏的替代方法是在调用someServiceEmittingEvents.subscribe
之前等待下一个滴答(使用像setTimeout
或setImmediate
这样的东西)。但是,这实际上只是我不推荐的解决方法。