Commit 84af6912 authored by Michael Underwood's avatar Michael Underwood
Browse files

Clear debounced event handlers on unmount

Resolves #231
parent 1d17ac11
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## [Unreleased]

### Fixed

- Debounced event handlers are now cleared on unmount, resolving
  [#231 Possible Regression](https://github.com/vue-leaflet/vue-leaflet/issues/231).


## [0.8.1] - 2023-01-29

### Fixed
+6 −6
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import {
  WINDOW_OR_GLOBAL,
  GLOBAL_LEAFLET_OPT,
  propsToLeafletOptions,
  cancelDebounces,
} from "../utils.js";
import { componentProps, setupComponent } from "../functions/component";

@@ -158,7 +159,7 @@ export default {
    provide(GLOBAL_LEAFLET_OPT, props.useGlobalLeaflet);

    const eventHandlers = {
      moveEndHandler() {
      moveEndHandler: debounce(() => {
        /**
         * Triggers when zoom is updated
         * @type {number,string}
@@ -175,7 +176,7 @@ export default {
         * @type {object}
         */
        context.emit("update:bounds", blueprint.leafletRef.getBounds());
      },
      }),
      overlayAddHandler(e) {
        const layer = blueprint.layersInControl.find((l) => l.name === e.name);
        if (layer) {
@@ -349,10 +350,7 @@ export default {
      propsBinder(methods, blueprint.leafletRef, props);
      const listeners = remapEvents(context.attrs);

      blueprint.leafletRef.on(
        "moveend",
        debounce(eventHandlers.moveEndHandler, 100)
      );
      blueprint.leafletRef.on("moveend", eventHandlers.moveEndHandler);
      blueprint.leafletRef.on("overlayadd", eventHandlers.overlayAddHandler);
      blueprint.leafletRef.on(
        "overlayremove",
@@ -364,6 +362,7 @@ export default {
    });

    onBeforeUnmount(() => {
      cancelDebounces(eventHandlers);
      if (blueprint.leafletRef) {
        blueprint.leafletRef.off();
        blueprint.leafletRef.remove();
@@ -372,6 +371,7 @@ export default {

    const leafletObject = computed(() => blueprint.leafletRef);
    const ready = computed(() => blueprint.ready);

    return { root, ready, leafletObject };
  },
  render() {
+16 −2
Original line number Diff line number Diff line
<script>
import { onMounted, ref, provide, inject, nextTick } from "vue";
import {
  onMounted,
  ref,
  provide,
  inject,
  nextTick,
  onBeforeUnmount,
} from "vue";
import {
  remapEvents,
  propsBinder,
  debounce,
  WINDOW_OR_GLOBAL,
  GLOBAL_LEAFLET_OPT,
  cancelDebounces,
} from "../utils.js";
import { markerProps, setupMarker } from "../functions/marker";
import { render } from "../functions/layer";
@@ -40,6 +48,10 @@ export default {
      delete options.icon;
    }

    const eventHandlers = {
      moveHandler: debounce(methods.latLngSync),
    };

    onMounted(async () => {
      const { marker, DomEvent } = useGlobalLeaflet
        ? WINDOW_OR_GLOBAL.L
@@ -49,7 +61,7 @@ export default {
      const listeners = remapEvents(context.attrs);
      DomEvent.on(leafletRef.value, listeners);

      leafletRef.value.on("move", debounce(methods.latLngSync, 100));
      leafletRef.value.on("move");
      propsBinder(methods, leafletRef.value, props);
      addLayer({
        ...props,
@@ -60,6 +72,8 @@ export default {
      nextTick(() => context.emit("ready", leafletRef.value));
    });

    onBeforeUnmount(() => cancelDebounces(eventHandlers));

    return { ready, leafletObject: leafletRef };
  },
  render() {
+16 −2
Original line number Diff line number Diff line
import { watch, ref, provide } from "vue";

export const debounce = (fn, time) => {
export const debounce = (fn, time = 100) => {
  let timeout;

  return function (...args) {
  const debounced = function (...args) {
    const context = this;
    if (timeout) {
      clearTimeout(timeout);
@@ -13,6 +13,20 @@ export const debounce = (fn, time) => {
      timeout = null;
    }, time);
  };

  debounced.cancel = function () {
    if (timeout) {
      clearTimeout(timeout);
    }
  };

  return debounced;
};

export const cancelDebounces = function (handlerMethods) {
  for (const handler of Object.values(handlerMethods)) {
    handler && isFunction(handler.cancel) && handler.cancel();
  }
};

export const capitalizeFirstLetter = (string) => {