我在BehaviorSubject
应用中使用了Angular
,从Details
可以观察到DataService
组件,如下所示:
DataService.ts:
export class DataService {
private messageTracker = new BehaviorSubject<any>();
private fileTracker = new BehaviorSubject<any>();
getMessageTracker(): Observable<any> {
return this.messageTracker.asObservable();
}
getFileTracker(): Observable<any> {
return this.fileTracker.asObservable();
}
//set methods omitted for brevity
}
DetailComponent:
export class DetailComponent implements OnInit {
subscription; //??? Can I use this variable for every subscription below?
constructor(private dataService: DataService) { }
ngOnInit(): void {
this.subscription = this.dataService.getMessageTracker().subscribe((param: any) => {
//...
});
this.subscription = this.dataService.getFileTracker().subscribe((param: any) => {
//...
});
}
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
我的问题是:
1)据我所知,如上所述,我应该为每个事件创建一个新的BehaviorSubject
变量,例如messageCreateTracker
(用于跟踪添加的新消息),fileCreateTracker
(用于跟踪添加的新文件,messageUpdateTracker
(用于跟踪更新的消息)。这一切都是真的吗?
2)在DetailComponent
中,我只为subscription
的每个订阅使用了一个Observables
变量。那是一个不好的方法吗?我应该为ngOnInit()
中的每个订阅创建一个新的订阅变量吗?
答案 0 :(得分:2)
回答查询1:
它取决于开发人员的编码风格,或者取决于他的想法,您还可以传递事件和数据的类型,在这种情况下,您将只需要一个BehaviorSubject
,就像这样:
this.messageTracker.next({ type : 'create' , data });
this.messageTracker.next({ type : 'update' , data });
this.messageTracker.next({ type : 'delete' , data });
但是如果它变大,也会产生复杂性,收益取决于项目的要求,您的方法也很好。
回答查询2:
基本上,您无法处理多个订阅,因为它将覆盖上一个订阅,而只会取消订阅最后一个订阅:
因此,您可以为订阅的或单个数组/对象创建多个变量,然后取消所有订阅:
使用数组:
this.subscription = [];
this.subscription.push(this.dataService.getMessageTracker().subscribe((param: any) => {}));
this.subscription.push(this.dataService.getFileTracker().subscribe((param: any) => {}));
ngOnDestroy(): void {
this.subscription.forEach(sub => {
sub.unsubscribe();
})
}
使用对象:
this.subscription = {};
this.subscription['messageTracker'] = this.dataService.getMessageTracker().subscribe((param: any) => {}));
this.subscription['fileTracker'] = this.dataService.getFileTracker().subscribe((param: any) => {}));
this.subscription['fileTracker'].unsubscribe(); // <--- You can also do
delete this.subscription['fileTracker']; // <--- then dont forgot to remove, or will throw error in ngOnDestroy
ngOnDestroy(): void {
for(key in this.subscription) {
this.subscription[key].unsubscribe();
}
}
答案 1 :(得分:1)
虽然标记的答案已得到很好的解释,但我想在这里分享我的一些想法。
问题1
BehaviorSubject
对象。BehaviorSubject
的任何内容。如果您尝试使用一个对象处理不同类型的数据,这将给您带来更多的复杂性。问题2
@Vivek指出,您的this.subscription
将在每个新订阅上覆盖上一个订阅。
为此,您可以使用 Subscription
类,
表示可抛弃的资源,例如Observable的执行。订阅具有一种重要的方法,即取消订阅,该方法不带任何参数,而是仅处理订阅所拥有的资源。
您可以通过两种方式使用它,
您可以直接将订阅推送到Subscription Array
subscriptions:Subscription[] = [];
ngOnInit(): void {
this.subscription.push(this.dataService.getMessageTracker().subscribe((param: any) => {
//...
}));
this.subscription.push(this.dataService.getFileTracker().subscribe((param: any) => {
//...
}));
}
ngOnDestroy(){
// prevent memory leak when component destroyed
this.subscriptions.forEach(s => s.unsubscribe());
}
使用add()
中的 Subscription
subscriptions = new Subscription();
this.subscriptions.add(subscribeOne);
this.subscriptions.add(subscribeTwo);
ngOnDestroy() {
this.subscriptions.unsubscribe();
}
Subscription
可以保留子订阅,并可以安全地取消订阅所有子订阅。此方法处理可能的错误(例如,如果任何子订阅为空)。
希望这会有所帮助..:)