Skip to content

Commit bc37310

Browse files
wnvkoLipata
andauthored
Destroy animation players and clean resources (#10267)
* fix(overlay): destroy animation players and clean resources, #8450 Co-authored-by: Milko Venkov <[email protected]> Co-authored-by: Nikolay Alipiev <[email protected]>
1 parent bb422f8 commit bc37310

File tree

3 files changed

+35
-10
lines changed

3 files changed

+35
-10
lines changed

projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ export class IgxToggleDirective implements IToggleView, OnInit, OnDestroy {
322322
if (this.navigationService && this.id) {
323323
this.navigationService.remove(this.id);
324324
}
325-
if (!this.collapsed && this._overlayId) {
325+
if (this._overlayId) {
326326
this.overlayService.detach(this._overlayId);
327327
}
328328
this.unsubscribe();

projects/igniteui-angular/src/lib/services/overlay/overlay.ts

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,9 @@ export class IgxOverlayService implements OnDestroy {
644644
// to eliminate flickering show the element just before animation start
645645
info.wrapperElement.style.visibility = 'hidden';
646646
}
647-
this.closed.emit({ id: info.id, componentRef: info.componentRef, event: info.event });
647+
if (!info.closeAnimationDetaching) {
648+
this.closed.emit({ id: info.id, componentRef: info.componentRef, event: info.event });
649+
}
648650
delete info.event;
649651
}
650652

@@ -659,15 +661,14 @@ export class IgxOverlayService implements OnDestroy {
659661
if (info.componentRef) {
660662
this._appRef.detachView(info.componentRef.hostView);
661663
info.componentRef.destroy();
664+
delete info.componentRef;
662665
}
663666
if (info.hook) {
664667
info.hook.parentElement.insertBefore(info.elementRef.nativeElement, info.hook);
665668
info.hook.parentElement.removeChild(info.hook);
666669
delete info.hook;
667670
}
668-
if (info.wrapperElement) {
669-
delete info.wrapperElement;
670-
}
671+
671672
const index = this._overlayInfos.indexOf(info);
672673
this._overlayInfos.splice(index, 1);
673674

@@ -679,6 +680,22 @@ export class IgxOverlayService implements OnDestroy {
679680
}
680681
this.removeCloseOnEscapeListener();
681682
}
683+
684+
// clean all the resources attached to info
685+
delete info.elementRef;
686+
delete info.settings;
687+
delete info.initialSize;
688+
info.openAnimationDetaching = true;
689+
info.openAnimationPlayer?.destroy();
690+
delete info.openAnimationPlayer;
691+
delete info.openAnimationInnerPlayer;
692+
info.closeAnimationDetaching = true;
693+
info.closeAnimationPlayer?.destroy();
694+
delete info.closeAnimationPlayer;
695+
delete info.closeAnimationInnerPlayer;
696+
delete info.ngZone;
697+
delete info.wrapperElement;
698+
info = null;
682699
}
683700

684701
private playOpenAnimation(info: OverlayInfo) {
@@ -924,7 +941,9 @@ export class IgxOverlayService implements OnDestroy {
924941
}
925942

926943
private openAnimationDone(info: OverlayInfo) {
927-
this.opened.emit({ id: info.id, componentRef: info.componentRef });
944+
if (!info.openAnimationDetaching) {
945+
this.opened.emit({ id: info.id, componentRef: info.componentRef });
946+
}
928947
if (info.openAnimationPlayer) {
929948
info.openAnimationPlayer.reset();
930949
// calling reset does not change hasStarted to false. This is why we are doing it here via internal field
@@ -940,7 +959,6 @@ export class IgxOverlayService implements OnDestroy {
940959
}
941960

942961
private closeAnimationDone(info: OverlayInfo) {
943-
this.closeDone(info);
944962
if (info.closeAnimationPlayer) {
945963
info.closeAnimationPlayer.reset();
946964
// calling reset does not change hasStarted to false. This is why we are doing it here via internal field
@@ -954,16 +972,17 @@ export class IgxOverlayService implements OnDestroy {
954972
// calling reset does not change hasStarted to false. This is why we are doing it here via internal field
955973
(info.openAnimationPlayer as any)._started = false;
956974
}
975+
this.closeDone(info);
957976
}
958977

959978
private finishAnimations(info: OverlayInfo) {
960979
// TODO: should we emit here opened or closed events
961-
if (info.openAnimationPlayer) {
980+
if (info.openAnimationPlayer && info.openAnimationPlayer.hasStarted()) {
962981
info.openAnimationPlayer.reset();
963982
// calling reset does not change hasStarted to false. This is why we are doing it here via internal field
964983
(info.openAnimationPlayer as any)._started = false;
965984
}
966-
if (info.closeAnimationPlayer) {
985+
if (info.closeAnimationPlayer && info.closeAnimationPlayer.hasStarted()) {
967986
info.closeAnimationPlayer.reset();
968987
// calling reset does not change hasStarted to false. This is why we are doing it here via internal field
969988
(info.closeAnimationPlayer as any)._started = false;

projects/igniteui-angular/src/lib/services/overlay/utilities.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,14 @@ export interface OverlayInfo {
147147
initialSize?: Size;
148148
hook?: HTMLElement;
149149
openAnimationPlayer?: AnimationPlayer;
150-
closeAnimationPlayer?: AnimationPlayer;
151150
openAnimationInnerPlayer?: any;
151+
// calling animation.destroy in detach fires animation.done. This should not happen
152+
// this is why we should trace if animation ever started
153+
openAnimationDetaching?: boolean;
154+
closeAnimationPlayer?: AnimationPlayer;
155+
// calling animation.destroy in detach fires animation.done. This should not happen
156+
// this is why we should trace if animation ever started
157+
closeAnimationDetaching?: boolean;
152158
closeAnimationInnerPlayer?: any;
153159
ngZone: NgZone;
154160
transformX?: number;

0 commit comments

Comments
 (0)