diff --git a/components/cascader/nz-cascader.component.ts b/components/cascader/nz-cascader.component.ts index da608957d89..c3c60d3120f 100644 --- a/components/cascader/nz-cascader.component.ts +++ b/components/cascader/nz-cascader.component.ts @@ -249,6 +249,8 @@ export class NzCascaderComponent implements NzCascaderComponentAsSource, OnInit, } ngOnDestroy(): void { + this.$destroy.next(); + this.$destroy.complete(); this.clearDelayMenuTimer(); this.clearDelaySelectTimer(); } diff --git a/components/checkbox/nz-checkbox-group.component.ts b/components/checkbox/nz-checkbox-group.component.ts index cd1239e8883..e2f96677b3b 100644 --- a/components/checkbox/nz-checkbox-group.component.ts +++ b/components/checkbox/nz-checkbox-group.component.ts @@ -13,6 +13,7 @@ import { Component, ElementRef, Input, + OnDestroy, OnInit, Renderer2, ViewEncapsulation @@ -42,7 +43,7 @@ export interface NzCheckBoxOptionInterface { } ] }) -export class NzCheckboxGroupComponent implements ControlValueAccessor, OnInit { +export class NzCheckboxGroupComponent implements ControlValueAccessor, OnInit, OnDestroy { // tslint:disable-next-line:no-any onChange: (value: any) => void = () => null; // tslint:disable-next-line:no-any @@ -75,6 +76,10 @@ export class NzCheckboxGroupComponent implements ControlValueAccessor, OnInit { }); } + ngOnDestroy(): void { + this.focusMonitor.stopMonitoring(this.elementRef); + } + writeValue(value: NzCheckBoxOptionInterface[]): void { this.options = value; this.cdr.markForCheck(); diff --git a/components/switch/nz-switch.component.ts b/components/switch/nz-switch.component.ts index d74da409c95..5d8810727b0 100644 --- a/components/switch/nz-switch.component.ts +++ b/components/switch/nz-switch.component.ts @@ -16,6 +16,7 @@ import { Component, ElementRef, Input, + OnDestroy, TemplateRef, ViewChild, ViewEncapsulation @@ -49,7 +50,7 @@ import { InputBoolean, NzSizeDSType } from 'ng-zorro-antd/core'; ` ] }) -export class NzSwitchComponent implements ControlValueAccessor, AfterViewInit { +export class NzSwitchComponent implements ControlValueAccessor, AfterViewInit, OnDestroy { checked = false; onChange: (value: boolean) => void = () => null; onTouched: () => void = () => null; @@ -113,6 +114,10 @@ export class NzSwitchComponent implements ControlValueAccessor, AfterViewInit { }); } + ngOnDestroy(): void { + this.focusMonitor.stopMonitoring(this.switchElement.nativeElement); + } + writeValue(value: boolean): void { this.checked = value; this.cdr.markForCheck(); diff --git a/components/tooltip/nz-tooltip.directive.ts b/components/tooltip/nz-tooltip.directive.ts index 061db435631..b9b217570a3 100644 --- a/components/tooltip/nz-tooltip.directive.ts +++ b/components/tooltip/nz-tooltip.directive.ts @@ -62,6 +62,7 @@ export class NzTooltipDirective implements AfterViewInit, OnChanges, OnInit, OnD ]; protected subs_ = new Subscription(); + protected listeners: Array<() => void> = []; @Output() readonly nzVisibleChange = new EventEmitter(); @@ -120,31 +121,48 @@ export class NzTooltipDirective implements AfterViewInit, OnChanges, OnInit, OnD ngAfterViewInit(): void { if (this.tooltip.nzTrigger === 'hover') { let overlayElement: HTMLElement; - this.renderer.listen(this.elementRef.nativeElement, 'mouseenter', () => + const listenerMouseEnter = this.renderer.listen(this.elementRef.nativeElement, 'mouseenter', () => this.delayEnterLeave(true, true, this.tooltip.nzMouseEnterDelay) ); - this.renderer.listen(this.elementRef.nativeElement, 'mouseleave', () => { + this.listeners.push(listenerMouseEnter); + + const listenerMouseLeave = this.renderer.listen(this.elementRef.nativeElement, 'mouseleave', () => { this.delayEnterLeave(true, false, this.tooltip.nzMouseLeaveDelay); if (this.tooltip.overlay.overlayRef && !overlayElement) { // NOTE: we bind events under "mouseleave" due to the overlayRef is only created after the overlay was completely shown up overlayElement = this.tooltip.overlay.overlayRef.overlayElement; - this.renderer.listen(overlayElement, 'mouseenter', () => this.delayEnterLeave(false, true)); - this.renderer.listen(overlayElement, 'mouseleave', () => this.delayEnterLeave(false, false)); + const listenerOverlayMouseEnter = this.renderer.listen(overlayElement, 'mouseenter', () => + this.delayEnterLeave(false, true) + ); + this.listeners.push(listenerOverlayMouseEnter); + + const listenerOverlayMouseLeave = this.renderer.listen(overlayElement, 'mouseleave', () => + this.delayEnterLeave(false, false) + ); + this.listeners.push(listenerOverlayMouseLeave); } }); + this.listeners.push(listenerMouseLeave); } else if (this.tooltip.nzTrigger === 'focus') { - this.renderer.listen(this.elementRef.nativeElement, 'focus', () => this.show()); - this.renderer.listen(this.elementRef.nativeElement, 'blur', () => this.hide()); + const listenerFocus = this.renderer.listen(this.elementRef.nativeElement, 'focus', () => this.show()); + this.listeners.push(listenerFocus); + + const listenerBlur = this.renderer.listen(this.elementRef.nativeElement, 'blur', () => this.hide()); + this.listeners.push(listenerBlur); } else if (this.tooltip.nzTrigger === 'click') { - this.renderer.listen(this.elementRef.nativeElement, 'click', e => { + const listenerClick = this.renderer.listen(this.elementRef.nativeElement, 'click', e => { e.preventDefault(); this.show(); }); + this.listeners.push(listenerClick); } } ngOnDestroy(): void { this.subs_.unsubscribe(); + this.listeners.forEach(listener => { + listener(); + }); } // tslint:disable-next-line:no-any