From 0375b49d6ae355317216020e3642123e7579f227 Mon Sep 17 00:00:00 2001 From: Aroooba Date: Tue, 24 Jan 2023 06:20:04 +0900 Subject: [PATCH] fix(sortable): unsubscribe item capture when component is destroyed Unsubscribed subscription in sortable component was causing memory to leak. We need to ensure all subscriptions are released whenever a component is destroyed. --- src/sortable/sortable.component.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/sortable/sortable.component.ts b/src/sortable/sortable.component.ts index 7761bc6394..c8cbf7fba0 100644 --- a/src/sortable/sortable.component.ts +++ b/src/sortable/sortable.component.ts @@ -4,12 +4,17 @@ import { Output, EventEmitter, forwardRef, - TemplateRef + TemplateRef, + OnDestroy, + HostListener, } from '@angular/core'; import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms'; import { DraggableItem } from './draggable-item'; import { DraggableItemService } from './draggable-item.service'; +import { takeUntil } from "rxjs/operators"; +import { Subject } from "rxjs"; + @Component({ selector: 'bs-sortable', exportAs: 'bs-sortable', @@ -53,8 +58,10 @@ import { DraggableItemService } from './draggable-item.service'; } ] }) -export class SortableComponent implements ControlValueAccessor { +export class SortableComponent implements ControlValueAccessor, OnDestroy { private static globalZoneIndex = 0; + private _destroy$: Subject = new Subject(); + /** field name if input array consists of objects */ @Input() fieldName?: string; @@ -121,6 +128,7 @@ export class SortableComponent implements ControlValueAccessor { this.currentZoneIndex = SortableComponent.globalZoneIndex++; this.transfer .onCaptureItem() + .pipe(takeUntil(this._destroy$)) .subscribe((item: DraggableItem) => this.onDrop(item)); } @@ -247,8 +255,13 @@ export class SortableComponent implements ControlValueAccessor { // with IE event.dataTransfer?.setData('Text', 'placeholder'); } -} + @HostListener('unloaded') + public ngOnDestroy(): void { + this._destroy$.next(true); + this._destroy$.complete(); + } +} export declare interface SortableItem { id: number; value: string;