uni-app unicloud-map回调函数@updated引起无限循环的问题

发布于 1周前 作者 gougou168 来自 Uni-App

uni-app unicloud-map回调函数@updated引起无限循环的问题

产品分类:uniCloud/App

操作步骤:

<unicloud-map ref="map" ...... [@updated](/user/updated)="onUpdated">
</unicloud-map>
onUpdated(e){
    //作用:
    //一旦地图重载数据,识别自己,并重新进行绘制。
    this.markers = this.$refs.map.getMarkers();  
    console.log("onReload get markers",this.markers );  
    //遍历数组,找到自己的标记点,更新各标记点的图标、文字,  
    for(var i in this.markers){  
        //如果当前显示所有用户方向  
        if(this.markers[i].ariaLabel==this.userInfo._id){  
            //自己  
            this.myMarker= Object.assign(this.markers[i]);                        
            if(this.showDir)this.markers[i].iconPath=this.directionMyImg;                         
        }else if(this.showDir){  
            this.markers[i].iconPath=this.directionImg;   
        }  

        if(this.hasNewCenter){  
            //如果当前在设计中心点,查看是否被选中,选中文字变色  
            if(this.paternerIDArr.indexOf(this.markers[i].ariaLabel)!=-1){  
                this.markers[i].callout.color="#ff0000";  
            }                     
        }  

    }  
    //计算绘制中心点及各标记点  
    if(this.hasNewCenter){  
        //如果当前正在设计中心点  
        this.centerMarker=-1;  
        this.computerCenter();  //重新计算绘制中心点(同时绘制所有点)                  

    }else{  
        this.$refs.map.setMarkers(this.markers);   
    }  
}

预期结果:

onUpdated()函数中执行:
this.$refs.map.setMarkers(this.markers);
会引起该函数再次被调用,形成无限循环。

实际结果:

onUpdated()函数中执行:
this.$refs.map.setMarkers(this.markers);
会引起该函数再次被调用,形成无限循环。

bug描述:

unicloud-map的回调函数[@updated](/user/updated)在地图渲染更新完成时触发,这个设计不好,因为每次刷新都会重新读取后台数据库中来生成marker数组,然后重新渲染地图中的标记点。这样会把用户对标记点的修改全部冲掉。为了保持用户的修改,只能在这个回调口再改回去,但是会导致无限循环,因为改完会引起新一轮的渲染,渲染结束后会再次调用回调函数,如此循环。

建议给unicloud-map增加一个[@reload](/user/reload)的回调函数,一旦数据从后台重新读取就触发这个回调。用户在此维护标记点信息,不会引起无限循环的问题。

3 回复

已确认,下版本新增 @load 事件 代表数据请求完成后的事件


点赞!响应迅速!我已经在官方代码上加了这个事件,名字叫@reload

在使用 UniApp 的 unicloud-map 组件时,如果你在 @updated 回调函数中修改了地图的状态(例如中心点、缩放级别等),可能会导致无限循环的问题。这是因为 @updated 事件会在每次地图状态发生变化时触发,如果你在回调函数中再次修改地图状态,就会再次触发 @updated 事件,从而形成无限循环。

解决方案

为了避免无限循环,你可以采取以下几种方法:

1. 使用标志位控制

你可以在回调函数中使用一个标志位来避免重复触发 @updated 事件。

<template>
  <unicloud-map @updated="onMapUpdated"></unicloud-map>
</template>

<script>
export default {
  data() {
    return {
      isUpdating: false
    };
  },
  methods: {
    onMapUpdated(e) {
      if (this.isUpdating) return;
      this.isUpdating = true;

      // 在这里执行你的逻辑,例如更新地图中心点或缩放级别
      // this.map.setCenter(newCenter);
      // this.map.setZoom(newZoom);

      this.isUpdating = false;
    }
  }
};
</script>

在这个例子中,isUpdating 标志位用于确保在 onMapUpdated 方法中不会重复触发 @updated 事件。

2. 避免在 @updated 中修改地图状态

如果可能的话,尽量避免在 @updated 回调函数中修改地图的状态。你可以在其他地方(例如用户交互事件)修改地图状态,而不是在 @updated 中。

3. 使用 @regionchange@moveend 事件

如果你只需要在地图移动或缩放结束时执行某些操作,可以考虑使用 @regionchange@moveend 事件,而不是 @updated。这些事件只会在用户交互结束后触发,避免了频繁触发的问题。

<template>
  <unicloud-map @moveend="onMapMoveEnd"></unicloud-map>
</template>

<script>
export default {
  methods: {
    onMapMoveEnd(e) {
      // 在这里执行你的逻辑
    }
  }
};
</script>

4. 使用 setTimeout 延迟执行

如果你确实需要在 @updated 中修改地图状态,可以使用 setTimeout 延迟执行,避免立即触发 @updated 事件。

<template>
  <unicloud-map @updated="onMapUpdated"></unicloud-map>
</template>

<script>
export default {
  methods: {
    onMapUpdated(e) {
      setTimeout(() => {
        // 在这里执行你的逻辑
      }, 100);
    }
  }
};
</script>
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!