每次加载组件时订阅数据增加 1
Subscription to data increases by 1 each time component loads
我在服务中使用以下方法向BehaviourSubject
注册数据。
regFieldsModules(fieldsModules?, field?: Field) {
// Using the previously stored data from the memory
if (fieldsModules) {
this.fieldMod = fieldsModules;
}
// Stop processing if fieldModules is null/ undefined
if (!this.fieldMod) {
return;
}
const groupFields = groupBy(this.fieldMod, 'id');
const uniqueFields: Field[] = removeDuplicates(this.fieldMod, 'id');
// Find the default field and assign it to the field
if (uniqueFields && !field) {
for (const f of uniqueFields) {
if (f.isDefault) {
field = f;
}
}
this.fields.next(uniqueFields);
}
this.field.next(field);
this.fieldModules.next(groupFields[field.id]);
}
并在组件中使用它作为:
ngOnInit() {
this.route.params.subscribe(params => {
this.dataService.fields.subscribe(fields => {
if (!fields) {
return;
}
for (const f of fields) {
if (+params['id'] === f.id) {
this.field = f;
this.dataService.regFieldsModules(null, this.field);
this.dataService.fieldModules.subscribe(data => {
if (data) {
console.log(data);
this.groupedModules = groupBy(data, 'moduleId');
}
});
}
}
});
});
}
第一次它控制台一次,如果我改变路线并再次访问路线它打印两次,第三次它打印第三次......它继续。数据变化无法退订,需要订阅
如果我在销毁时取消订阅所有订阅,这可能会解决,但我有另一个用户案例:
我已经下拉了 header。在选择时,参数会更改并且组件会刷新。在这种情况下,不会调用 OnDestroy
方法。
上面的代码有没有更好的写法?
每次销毁组件时,您都必须取消订阅对外部服务的所有订阅,否则您将在应用程序中造成内存泄漏,使用嵌套订阅而不是高阶运算符也会造成泄漏。这是正确的做法:
this.sub = combineLatest(this.route.params, this.dataService.fields) // combine subscriptions that don't rely on eachother
.pipe(
switchMap(([params, fields]) => { //switchMap into new observables to auto cancel previous subscriptions on new emissions
if (!fields) {
return EMPTY; // return empty to not emit in the no fields case
}
const field = fields.find(f => +params['id'] === f.id); // find instead of looping
this.field = field; // this block is problematic. Why are you creating side effects here?
this.dataService.regFieldsModules(null, this.field);
return this.dataService.fieldModules; // why switch into a new observable after calling that method?
})
).subscribe(data => { // now I've got the data
if (data) {
console.log(data);
this.groupedModules = groupBy(data, 'moduleId');
}
});
然后在 ngOnDestroy 运行:
this.sub.unsubscribe();
我在服务中使用以下方法向BehaviourSubject
注册数据。
regFieldsModules(fieldsModules?, field?: Field) {
// Using the previously stored data from the memory
if (fieldsModules) {
this.fieldMod = fieldsModules;
}
// Stop processing if fieldModules is null/ undefined
if (!this.fieldMod) {
return;
}
const groupFields = groupBy(this.fieldMod, 'id');
const uniqueFields: Field[] = removeDuplicates(this.fieldMod, 'id');
// Find the default field and assign it to the field
if (uniqueFields && !field) {
for (const f of uniqueFields) {
if (f.isDefault) {
field = f;
}
}
this.fields.next(uniqueFields);
}
this.field.next(field);
this.fieldModules.next(groupFields[field.id]);
}
并在组件中使用它作为:
ngOnInit() {
this.route.params.subscribe(params => {
this.dataService.fields.subscribe(fields => {
if (!fields) {
return;
}
for (const f of fields) {
if (+params['id'] === f.id) {
this.field = f;
this.dataService.regFieldsModules(null, this.field);
this.dataService.fieldModules.subscribe(data => {
if (data) {
console.log(data);
this.groupedModules = groupBy(data, 'moduleId');
}
});
}
}
});
});
}
第一次它控制台一次,如果我改变路线并再次访问路线它打印两次,第三次它打印第三次......它继续。数据变化无法退订,需要订阅
如果我在销毁时取消订阅所有订阅,这可能会解决,但我有另一个用户案例:
我已经下拉了 header。在选择时,参数会更改并且组件会刷新。在这种情况下,不会调用 OnDestroy
方法。
上面的代码有没有更好的写法?
每次销毁组件时,您都必须取消订阅对外部服务的所有订阅,否则您将在应用程序中造成内存泄漏,使用嵌套订阅而不是高阶运算符也会造成泄漏。这是正确的做法:
this.sub = combineLatest(this.route.params, this.dataService.fields) // combine subscriptions that don't rely on eachother
.pipe(
switchMap(([params, fields]) => { //switchMap into new observables to auto cancel previous subscriptions on new emissions
if (!fields) {
return EMPTY; // return empty to not emit in the no fields case
}
const field = fields.find(f => +params['id'] === f.id); // find instead of looping
this.field = field; // this block is problematic. Why are you creating side effects here?
this.dataService.regFieldsModules(null, this.field);
return this.dataService.fieldModules; // why switch into a new observable after calling that method?
})
).subscribe(data => { // now I've got the data
if (data) {
console.log(data);
this.groupedModules = groupBy(data, 'moduleId');
}
});
然后在 ngOnDestroy 运行:
this.sub.unsubscribe();