在扩展 class 的构造函数中订阅无法正常工作
Subscribing within constructor of extended class does not work correctly
我构建了一个名为 CoreButtonService 的抽象 class,每个 ButtonService 都会扩展它。比如有UserButtonService、MessageButtonService等。这些服务将被注入到相应的组件中,如 UserComponent、MessageComponent 等。在 CoreButtonService 的构造函数中,我订阅了另一个名为 ButtonsService 的服务,该服务负责在单击 ButtonModule 中的任何按钮时触发事件。
CoreButtonService:
export abstract class CoreButtonService<T extends CoreModel> extends CoreService {
private backSource = new Subject<string>();
private submitSource = new Subject<string>();
back$ = this.backSource.asObservable();
submit$ = this.submitSource.asObservable();
constructor(
private coreButtonsService: ButtonsService,
private coreLanguageService: LanguageService,
private coreLocation: Location) {
super(coreLanguageService);
this.coreButtonsService
.buttonClicked$
.subscribe(button => console.log(button)); // !!!!!!
}
// Buttons are going to be built down here ...
}
按钮服务:
@Injectable()
export class ButtonsService {
private button = new Subject<ButtonBase<any>>();
buttonClicked$ = this.button.asObservable();
constructor(private formService: FormService) { }
clickButton(button: ButtonBase<any>): void {
if (button.controlType === 'submit')
this.formService.submitForm(button.parent);
this.button.next(button);
}
}
假设我访问包含 UserComponent 的页面,单击一个按钮,然后在 MessageComponent 的页面上执行相同的操作。从技术上讲,控制台中应该记录 2 个按钮。我可以通过 button.parent
来识别 UserComponent 的按钮和 MessageComponent 的按钮。但是我得到了 MessageComponent 的 2 个按钮。
当我将发送的父级保存在 CoreButtonService 中并像按钮一样记录它时,我得到了预期值:MessageComponent 为 'MessageForm',UserComponent 为 'UserForm'。但是 button.parent
的值是相同的。这怎么可能?
我没有看到问题。可能是因为每个 ButtonService 都在 CoreButtonService 中进行相同的订阅,这就是每个订阅/按钮彼此相关的原因?
更新
这是plunkr的基本概念。
我终于找到了错误,这是一个非常愚蠢的错误。在 CoreComponent 中我退订了
ngOnDestroy() {
this.subscription.unsubscribe;
}
而不是 unsubscribe()
。所以事情变得有点疯狂。不过还是谢谢你的帮助。
更详细地解释@user289520的解决方案:
Subscriptions
:表示一次性资源,比如一个Observable的执行。订阅有一个重要的方法,unsubscribe
,它不带参数,只处理订阅持有的资源。
您可以在 ngOnDestroy()
.
中一次性收集您想要 unsubscribe
的订阅
ngOnDestroy()
:在 Angular 破坏 directive/component 之前清理。取消订阅可观察对象并分离事件处理程序以避免内存泄漏。
然而,除了 this.subscription.unsubscribe;
之外,您还可以在 foreach
循环中执行此操作,如下所示:
this.subscriptions.forEach(s => s.unsubscribe());
为什么你不应该在 angular.js
中忘记 unsubscribe()
?
- Promise 是急切的并且会立即执行。 Observables 并不急切,仅在
subscribed
到 时执行
- 承诺是
asynchronous
。 Observable 可以是 synchronous or asynchronous.
- Promises 预计 return 只有一个值(如函数)。 Observables 可以 return 零、一个或多个(无限)值。
我构建了一个名为 CoreButtonService 的抽象 class,每个 ButtonService 都会扩展它。比如有UserButtonService、MessageButtonService等。这些服务将被注入到相应的组件中,如 UserComponent、MessageComponent 等。在 CoreButtonService 的构造函数中,我订阅了另一个名为 ButtonsService 的服务,该服务负责在单击 ButtonModule 中的任何按钮时触发事件。
CoreButtonService:
export abstract class CoreButtonService<T extends CoreModel> extends CoreService {
private backSource = new Subject<string>();
private submitSource = new Subject<string>();
back$ = this.backSource.asObservable();
submit$ = this.submitSource.asObservable();
constructor(
private coreButtonsService: ButtonsService,
private coreLanguageService: LanguageService,
private coreLocation: Location) {
super(coreLanguageService);
this.coreButtonsService
.buttonClicked$
.subscribe(button => console.log(button)); // !!!!!!
}
// Buttons are going to be built down here ...
}
按钮服务:
@Injectable()
export class ButtonsService {
private button = new Subject<ButtonBase<any>>();
buttonClicked$ = this.button.asObservable();
constructor(private formService: FormService) { }
clickButton(button: ButtonBase<any>): void {
if (button.controlType === 'submit')
this.formService.submitForm(button.parent);
this.button.next(button);
}
}
假设我访问包含 UserComponent 的页面,单击一个按钮,然后在 MessageComponent 的页面上执行相同的操作。从技术上讲,控制台中应该记录 2 个按钮。我可以通过 button.parent
来识别 UserComponent 的按钮和 MessageComponent 的按钮。但是我得到了 MessageComponent 的 2 个按钮。
当我将发送的父级保存在 CoreButtonService 中并像按钮一样记录它时,我得到了预期值:MessageComponent 为 'MessageForm',UserComponent 为 'UserForm'。但是 button.parent
的值是相同的。这怎么可能?
我没有看到问题。可能是因为每个 ButtonService 都在 CoreButtonService 中进行相同的订阅,这就是每个订阅/按钮彼此相关的原因?
更新
这是plunkr的基本概念。
我终于找到了错误,这是一个非常愚蠢的错误。在 CoreComponent 中我退订了
ngOnDestroy() {
this.subscription.unsubscribe;
}
而不是 unsubscribe()
。所以事情变得有点疯狂。不过还是谢谢你的帮助。
更详细地解释@user289520的解决方案:
Subscriptions
:表示一次性资源,比如一个Observable的执行。订阅有一个重要的方法,unsubscribe
,它不带参数,只处理订阅持有的资源。
您可以在 ngOnDestroy()
.
unsubscribe
的订阅
ngOnDestroy()
:在 Angular 破坏 directive/component 之前清理。取消订阅可观察对象并分离事件处理程序以避免内存泄漏。
然而,除了 this.subscription.unsubscribe;
之外,您还可以在 foreach
循环中执行此操作,如下所示:
this.subscriptions.forEach(s => s.unsubscribe());
为什么你不应该在 angular.js
中忘记 unsubscribe()
?
- Promise 是急切的并且会立即执行。 Observables 并不急切,仅在
subscribed
到 时执行
- 承诺是
asynchronous
。 Observable 可以是 synchronous or asynchronous. - Promises 预计 return 只有一个值(如函数)。 Observables 可以 return 零、一个或多个(无限)值。