Ver Fonte

fix(gis): cleanup map loading and simplify imports

Kazerin há 1 mês atrás
pai
commit
1509207893

+ 20 - 3
src/components/GisMapCanvas.vue

@@ -23,6 +23,8 @@ const mapContainer = ref(null)
 const mapError = ref('')
 const mapError = ref('')
 let mapInstance = null
 let mapInstance = null
 let overlays = []
 let overlays = []
+let bmapLoadTimer = null
+let disposed = false
 
 
 const convertedCenter = computed(() => convertCoord(props.center.lng, props.center.lat))
 const convertedCenter = computed(() => convertCoord(props.center.lng, props.center.lat))
 
 
@@ -41,16 +43,25 @@ function waitForBMapGL() {
       resolve(window.BMapGL)
       resolve(window.BMapGL)
       return
       return
     }
     }
+    if (disposed) {
+      reject(new Error('GIS map component disposed'))
+      return
+    }
     let attempts = 0
     let attempts = 0
-    const timer = setInterval(() => {
+    bmapLoadTimer = setInterval(() => {
       attempts += 1
       attempts += 1
+      if (disposed) {
+        clearInterval(bmapLoadTimer)
+        reject(new Error('GIS map component disposed'))
+        return
+      }
       if (window.BMapGL) {
       if (window.BMapGL) {
-        clearInterval(timer)
+        clearInterval(bmapLoadTimer)
         resolve(window.BMapGL)
         resolve(window.BMapGL)
         return
         return
       }
       }
       if (attempts >= 100) {
       if (attempts >= 100) {
-        clearInterval(timer)
+        clearInterval(bmapLoadTimer)
         reject(new Error('百度地图加载超时'))
         reject(new Error('百度地图加载超时'))
       }
       }
     }, 200)
     }, 200)
@@ -61,6 +72,7 @@ async function initMap() {
   if (!mapContainer.value) return
   if (!mapContainer.value) return
   try {
   try {
     const BMapGL = await waitForBMapGL()
     const BMapGL = await waitForBMapGL()
+    if (disposed || !mapContainer.value) return
     mapInstance = new BMapGL.Map(mapContainer.value, { enableMapClick: true })
     mapInstance = new BMapGL.Map(mapContainer.value, { enableMapClick: true })
     const [lng, lat] = convertedCenter.value
     const [lng, lat] = convertedCenter.value
     mapInstance.centerAndZoom(new BMapGL.Point(lng, lat), props.zoom)
     mapInstance.centerAndZoom(new BMapGL.Point(lng, lat), props.zoom)
@@ -223,6 +235,11 @@ onMounted(async () => {
 })
 })
 
 
 onBeforeUnmount(() => {
 onBeforeUnmount(() => {
+  disposed = true
+  if (bmapLoadTimer) {
+    clearInterval(bmapLoadTimer)
+    bmapLoadTimer = null
+  }
   clearScene()
   clearScene()
   try {
   try {
     mapInstance?.destroy()
     mapInstance?.destroy()

+ 1 - 2
src/views/subSystem/waterSupply/components/WaterAlarmPage.vue

@@ -274,9 +274,8 @@
         resolveAlarm
         resolveAlarm
     } from '@/api/pipeNetwork/waterSupply'
     } from '@/api/pipeNetwork/waterSupply'
     import GisMapCanvas from '@/components/GisMapCanvas.vue'
     import GisMapCanvas from '@/components/GisMapCanvas.vue'
-    import { getMonitoringPointColor } from '@/utils/gisMapColors'
+    import { getMonitoringPointColor, getMonitoringPointIcon } from '@/utils/gisMapColors'
     import {normalizeMapPoints, normalizePage, unwrapResponse} from '@/utils/waterSupplyModel'
     import {normalizeMapPoints, normalizePage, unwrapResponse} from '@/utils/waterSupplyModel'
-import { getMonitoringPointIcon } from '@/utils/gisMapColors'
     import {getRequestErrorMessage} from '@/utils/waterFacilityQuery'
     import {getRequestErrorMessage} from '@/utils/waterFacilityQuery'
 
 
     const props = defineProps({
     const props = defineProps({

+ 6 - 0
tests/gisMapCanvas.test.mjs

@@ -17,6 +17,12 @@ test('shared gis map canvas renders every point as an official icon with a label
   const source = await readFile('src/components/GisMapCanvas.vue', 'utf8')
   const source = await readFile('src/components/GisMapCanvas.vue', 'utf8')
 
 
   assert.match(source, /function escapeHtml\(value\)/u)
   assert.match(source, /function escapeHtml\(value\)/u)
+  assert.match(source, /let bmapLoadTimer = null/u)
+  assert.match(source, /let disposed = false/u)
+  assert.match(source, /if \(disposed\) \{[\s\S]*?clearInterval\(bmapLoadTimer\)/u)
+  assert.match(source, /if \(disposed \|\| !mapContainer\.value\) return/u)
+  assert.match(source, /onBeforeUnmount\(\(\) => \{[\s\S]*?disposed = true/u)
+  assert.match(source, /clearInterval\(bmapLoadTimer\)/u)
   assert.match(source, /markerSize: \{ type: Number, default: 28 \}/u)
   assert.match(source, /markerSize: \{ type: Number, default: 28 \}/u)
   assert.match(source, /const iconUrl = point\.iconUrl \|\| getMonitoringPointIcon\(point\)/u)
   assert.match(source, /const iconUrl = point\.iconUrl \|\| getMonitoringPointIcon\(point\)/u)
   assert.match(source, /new BMapGL\.Icon\(iconUrl, new BMapGL\.Size\(size, size\), \{/u)
   assert.match(source, /new BMapGL\.Icon\(iconUrl, new BMapGL\.Size\(size, size\), \{/u)