From 770b01499b0de7d0c98db68f0d56165def759892 Mon Sep 17 00:00:00 2001 From: Johan Groth Date: Fri, 29 Mar 2019 08:48:59 +0100 Subject: [PATCH] perf(mdc): remove event listeners when components are destroyed --- src/components/dialog/dialog.tsx | 51 +++++++++++++++++----------- src/components/slider/slider.tsx | 1 + src/components/snackbar/snackbar.tsx | 26 +++++++++----- 3 files changed, 51 insertions(+), 27 deletions(-) diff --git a/src/components/dialog/dialog.tsx b/src/components/dialog/dialog.tsx index 2b947c6c1e..314c1943bb 100644 --- a/src/components/dialog/dialog.tsx +++ b/src/components/dialog/dialog.tsx @@ -64,6 +64,12 @@ export class Dialog { private id: string; + constructor() { + this.handleMdcOpened = this.handleMdcOpened.bind(this); + this.handleMdcClosed = this.handleMdcClosed.bind(this); + this.handleMdcClosing = this.handleMdcClosing.bind(this); + } + public componentWillLoad() { this.id = createRandomString(); } @@ -90,25 +96,9 @@ export class Dialog { deactivate(); }; - this.mdcDialog.listen('MDCDialog:opened', () => { - // When the opening-animation has completed, dispatch a - // resize-event so that any content that depends on - // javascript for layout has a chance to update to the - // final layout of the dialog. /Ads - dispatchResizeEvent(); - }); - - this.mdcDialog.listen('MDCDialog:closed', () => { - if (this.open) { - this.close.emit(); - } - - this.open = false; - }); - - this.mdcDialog.listen('MDCDialog:closing', () => { - this.closing.emit(); - }); + this.mdcDialog.listen('MDCDialog:opened', this.handleMdcOpened); + this.mdcDialog.listen('MDCDialog:closed', this.handleMdcClosed); + this.mdcDialog.listen('MDCDialog:closing', this.handleMdcClosing); this.mdcDialog.scrimClickAction = this.closingActions.scrimClick ? 'close' @@ -119,6 +109,9 @@ export class Dialog { } public componentDidUnload() { + this.mdcDialog.unlisten('MDCDialog:opened', this.handleMdcOpened); + this.mdcDialog.unlisten('MDCDialog:closed', this.handleMdcClosed); + this.mdcDialog.unlisten('MDCDialog:closing', this.handleMdcClosing); this.mdcDialog.destroy(); } @@ -168,6 +161,26 @@ export class Dialog { } } + private handleMdcOpened() { + // When the opening-animation has completed, dispatch a + // resize-event so that any content that depends on + // javascript for layout has a chance to update to the + // final layout of the dialog. /Ads + dispatchResizeEvent(); + } + + private handleMdcClosed() { + if (this.open) { + this.close.emit(); + } + + this.open = false; + } + + private handleMdcClosing() { + this.closing.emit(); + } + private renderHeading() { if (this.heading) { return

{this.heading.trim()}

; diff --git a/src/components/slider/slider.tsx b/src/components/slider/slider.tsx index 3b9b0ba0d6..c997c0d60d 100644 --- a/src/components/slider/slider.tsx +++ b/src/components/slider/slider.tsx @@ -54,6 +54,7 @@ export class Slider { } public componentDidUnload() { + this.mdcSlider.unlisten('MDCSlider:change', this.changeHandler); this.mdcSlider.destroy(); } diff --git a/src/components/snackbar/snackbar.tsx b/src/components/snackbar/snackbar.tsx index 2b74e51cca..79c7f63d91 100644 --- a/src/components/snackbar/snackbar.tsx +++ b/src/components/snackbar/snackbar.tsx @@ -1,4 +1,7 @@ -import { MDCSnackbar } from '@lime-material-16px/snackbar'; +import { + MDCSnackbar, + MDCSnackbarCloseEvent, +} from '@lime-material-16px/snackbar'; import { Component, Element, @@ -55,21 +58,20 @@ export class Snackbar { private mdcSnackbar: MDCSnackbar; + constructor() { + this.handleMdcClosing = this.handleMdcClosing.bind(this); + } + public componentDidLoad() { this.mdcSnackbar = new MDCSnackbar( this.host.shadowRoot.querySelector('.mdc-snackbar') ); - this.mdcSnackbar.listen('MDCSnackbar:closing', event => { - if (event.detail.reason === 'action') { - this.action.emit(); - } else { - this.hide.emit(); - } - }); + this.mdcSnackbar.listen('MDCSnackbar:closing', this.handleMdcClosing); } public componentDidUnload() { + this.mdcSnackbar.unlisten('MDCSnackbar:closing', this.handleMdcClosing); this.mdcSnackbar.destroy(); } @@ -109,6 +111,14 @@ export class Snackbar { ); } + private handleMdcClosing(event: MDCSnackbarCloseEvent) { + if (event.detail.reason === 'action') { + this.action.emit(); + } else { + this.hide.emit(); + } + } + private renderAction(actionText) { if (actionText) { return (