【发布时间】:2018-09-20 22:15:07
【问题描述】:
我了解到您在删除组件时应始终取消订阅。在我的情况下,当另一个子路由被激活并因此另一个子组件取代前一个组件时,就会发生这种情况。当我导航回第一个组件时,我收到错误object unsubscribed,即使我再次订阅了behavioursubject。防止此错误的唯一方法是从 ngOnDestroy 中删除取消订阅代码,但随后行为主题永远不会被取消订阅。所以我比较困惑。我应该什么时候退订?如果不是在删除子组件时,那是什么时候?这是我的代码:
export class TemperatureSettingsComponent implements OnInit, OnDestroy {
data: any;
temperatureForm: FormGroup;
monthlyTemperatureCurve: number[];
saveToLocalStorage:BehaviorSubject<any[]> = this.seedCalendarService.getSaveBehaviorSubject();
useImperialMeasureSystem: boolean = true;
options = {
responsive: false,
maintainAspectRatio: false
};
constructor(private fb: FormBuilder,
private seedCalendarService: SeedCalendarService,
private notificationService: NotificationService,
private dataStoreService: DataStoreService) {
this.saveToLocalStorage.subscribe(pair => {
if(pair[0] === DataType.MEASURE_SYSTEM_PREFERENCE){
this.useImperialMeasureSystem = pair[1];
}
});
this.temperatureForm = fb.group({
'january' : [''],
'february' : [''],
'march' : [''],
'april' : [''],
'may' : [''],
'june' : [''],
'july' : [''],
'august' : [''],
'september' : [''],
'october' : [''],
'november' : [''],
'december' : ['']
});
}
ngOnDestroy(){
this.saveToLocalStorage.unsubscribe();
}
您可以清楚地看到我正在重新订阅构造函数中的behaviorsubjet toLocalStorage,但似乎只允许订阅和取消订阅子组件的第一个实例。正在加载的子组件的每个连续实例都无法重新订阅,我觉得这很令人困惑,因为它是一个新实例。请解释一下,谢谢。
【问题讨论】:
-
在主题上调用
unsubscribe会使其关闭且不再可用。看看this article。 -
和Router的events对象,我可以取消订阅,然后在我选择的时候重新订阅对象,这个对象和主题不同吗?
-
如果你订阅了 observable 并收到了订阅,是的,你可以在订阅上调用
unsubscribe。只有主题是特例。而Subject.prototype.unsubscribe很可能在 RxJS v7 中被移除;这很令人困惑——因为它与订阅无关;它与其他 Rx 实现中的处置概念更密切相关 - 并不是特别有用。 -
好的,总结一下你刚才所说的。您可以根据需要订阅和取消订阅,然后重新订阅可观察对象,而 BehaviorSubject 只能取消订阅一次。当您从程序中的某处调用 unsubscribe() 时,所有订阅者都无法访问 Behaviorsubject。这是正确的吗?
-
是的,在
Subcription上调用unsubscribe到任何东西 - 甚至是主题 - 都很好,但是在主题上 直接 调用unsubscribe将关闭/处置/销毁该主题。我写了一个 TSLint 规则来禁止它,这是一件不太可能的事情:rxjs-no-subject-unsubscribe.
标签: angular typescript