uni-app unicloud-map回调函数@updated引起无限循环的问题
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>