我有一个地址组件,是通过*ngIf
切换的.此地址组件包含一个mat-autocomplete
(摘录):
address-component.html
<mat-form-field class="full-width" appearance="outline">
<mat-label>Straße</mat-label>
<input matInput [matAutocomplete]="auto" type="text" [formControlName]="formControlMapping.street" />
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option *ngFor="let street of streets$ | async" [value]="street">
{{ street }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
mat-autocomplete
的不同选项是从BehaviorSubject
派生的。为了防止内存泄漏,我在complete
和unsubscribe
中使用ngOnDestroy
。尽管如此,我还是设法产生了内存泄漏,因为在通过*ngIf
切换组件并试图将新值写入BehaviorSubject
后,我得到了以下错误。
ObjectUnsubscribedErrorImpl {message: "object unsubscribed", name: "ObjectUnsubscribedError"}
我做错了什么?我在哪里产生内存泄漏?
address-component.ts
export class AddressFormComponent implements OnInit, OnDestroy {
@Input() formGroup: FormGroup;
public streetSubject = new BehaviorSubject<string[]>([]);
public streets$: Observable<string[]>;
ngOnInit(): void {
...
this.formGroup.get(this.formControlMapping.zipCode).valueChanges.subscribe({
next: () => {
this.addressService
.getStreets()
.pipe(
tap((streets) => {
this.streetSubject.next(streets);
this.streets$ = of(this.filter(this.formGroup.get(this.formControlMapping.street).value, streets));
})
)
.subscribe();
}
});
...
this.disableDependingForms();
}
disableDependingForms(): void {
...
this.addressService.getStreets().subscribe({
next: (val) => {
const street = this.formGroup.get(this.formControlMapping.street).value;
this.streetSubject.next(val);
this.streets$ = this.streetSubject.pipe(map((streets) => this.filter(street, streets)));
}
});
...
}
ngOnDestroy(): void {
this.streetSubject.complete();
this.streetSubject.unsubscribe();
}
}
编辑:
我的目标是:根据zipCode的值,我需要从api中获取位于zipCode区域的街道。有几个其他条件必须满足,才能找到街道,但这些条件是静止的,不会使任何事情复杂化。当zipCode
值发生变化时,街道将被更新。基本上:根据名为formControl
zipCode.
的值从API获取街道
泄漏的原因是调用this.streetSubject.next(streets);
The next
。
我试过了,但ObjectUnsubscribedErrorImpl
仍然存在。有什么建议吗?
this.formGroup
.get(this.formControlMapping.zipCode)
.valueChanges.pipe(
switchMap((zipCode: string) => {
return this.addressService.getStreets().pipe(
map((val) => ({ streets: val, zipCode })),
takeUntil(this.unsubscribe)
);
}),
takeUntil(this.unsubscribe)
)
.subscribe({
next: ({ zipCode, streets }) => {
...
this.streetSubject.next(streets);
...
}
});
发布于 2020-05-26 10:53:34
当然,通过takeUntil
取消订阅的正确方法是:
ngOnDestroy(): void {
this.unsubscribe.next();
this.streetSubject.complete();
}
不是:
ngOnDestroy(): void {
this.streetSubject.complete();
this.streetSubject.unsubscribe();
}
使用正确的方法进行unsubscribe
,一切都很好。
发布于 2020-05-22 15:02:57
你从来不取消订阅这些
this.formGroup.get(this.formControlMapping.zipCode).valueChanges.subscribe(
如果getStreets
不是web请求,它也可能是泄漏的。
this.addressService.getStreets().subscribe({
https://stackoverflow.com/questions/61957895
复制相似问题