Dafrok / vue-baidu-map

Baidu Map components for Vue 2.x
https://dafrok.github.io/vue-baidu-map/
MIT License
2.41k stars 430 forks source link

覆盖物点击事件回调方法中数据未能正确的赋值给data #564

Open yangtoude opened 5 years ago

yangtoude commented 5 years ago

[BUG 反馈] 覆盖物点击事件回调方法中数据未能正确的赋值给data

浏览器版本号

chrome Version 72.0.3626.96 (Official Build) (64-bit)

Vue 版本号

2.5.2

组件库版本号

0.21.11

现象描述

问题:点击覆盖物时,数据未能正确的赋值给data,导致显示该覆盖物信息的infowindow定位和展示的数据不能对应起来

相关代码

# template
<bm-marker v-for="(marker,index) in markers" :key="index" :position="{lng: marker.lng, lat: marker.lat}"
    :rotation="getRotation(marker.azimuth)" :icon="getIcon(marker.type, marker.isCenter)"
  :zIndex="zIndex" :offset="getOffsetData(marker.azimuth)" @click="showInfoWindow(marker)">
</bm-marker>

# data和methods
data() {
  return {
    // ...
    markers: [], // !!! 注意:markers是从后段异步获取
    infoWindow: {
      show: false,
      data: {}
    }
  }
},
methods() {
  // 异步获取覆盖物列表
  getQuitList() {
    this.loading.map = true

    getQuitList(query)
      .then(res => {
        this.loading.map = false

        const usData = res.data
        if (usData.code === 0) {
          const sData = usData.data.all
          const len = sData.length

          if (Array.isArray(sData) && len > 0) {
              // 绘制基站和小区
            const sMarkers = []
            for (let i = 0; i < len; i++) {
              const item = sData[i]

              if (item.latitude !== null && item.longtitude !== null) {
                sMarkers.push({
                  orignalLat: item.latitude,
                  orignalLng: item.longtitude,
                  lat: item.latBd09,
                  lng: item.lonBd09,
                  name: item.name,
                  type: item.type,
                  quitInfo: this.typeInfoMap[item.type],
                  code: item.code,
                  azimuth: item.azimuth
                })
              }
            }

            this.setCenterByCity()
            this.initCenter = this.center
            this.markers = sMarkers
          } else {
            // ...
          }
        } else {
          // ...
        }
      })
      .catch(err => {
        // ...
      })
  showInfoWindow(marker) {
    this.infoWindow.data = marker // !!!问题:点击时传入的marker不是当前点击的marker
    this.openWindow()
  }
}

完整异常信息

暂无

在线示例 / 仓库 URL

暂无

复现用例

暂无
注意:不是所有的覆盖物都有这个问题,每次只有几个有这样的问题

预期输出

点击时showInfoWindow传入的marker应该是当前点击的marker

实际输出

点击时showInfoWindow传入的marker不是当前点击的marker
Dafrok commented 5 years ago

没看出问题,https://codesandbox.io/ 写个示例?另外 InfoWindow 是可以作为 Marker 的子组件的,文档里有写。

yangtoude commented 5 years ago

好的,我先试试写个示例。我也试了把InfoWindow作为Marker的子组件,但这个问题仍然存在。我用VueDevtools看了下data中的数据发现点击覆盖物时绑定在InfoWindow组件中的数据没有及时更新,我觉得这个应该是导致InfoWindow展示的位置和信息和当前点击的覆盖物信息不一致的原因,但不知道为什么会出现这种情况。

On Feb 14, 2019, at 7:40 PM, 马金花儿 notifications@github.com wrote:

没看出问题,https://codesandbox.io/ https://codesandbox.io/ 写个示例?另外 InfoWindow 是可以作为 Marker 的子组件的,文档里有写。

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Dafrok/vue-baidu-map/issues/564#issuecomment-463596814, or mute the thread https://github.com/notifications/unsubscribe-auth/AQggPqXd-3ynyJ_1OAfQ-_ulAao2CCoFks5vNUtEgaJpZM4a6wZG.

yangtoude commented 5 years ago

示例:https://codesandbox.io/s/xr13y856jq 我还顺便把示例放在了github上:https://github.com/yangtoude/vue-baidu-map-marker-click-bug 依次点击“加载基站”、“加载小区”、“加载基站和小区”三个按钮,然后再点击一些地图中加载的覆盖物图形就可以复现这个bug。 image

Dafrok commented 5 years ago

复现了,我周末 review 一下

yangtoude commented 5 years ago

好的

yangtoude commented 5 years ago

哥们,有解决思路了么?

Dafrok commented 5 years ago

这个问题看起来还挺麻烦的,一直没抽出大块时间来解决,抱歉

yangtoude commented 5 years ago

没事,我暂时先通过script标签引入的方式把百度api全局引入,有问题的页面暂时不用vue-baidu-map,用原生的方式写了下,你慢慢找原因。不过我也很好奇为什么会出这个bug,解决了的话,一定得告诉我下^_^。

Dafrok commented 5 years ago

ok,解决的话我会把 commit 直接关联到这里

17605094230 commented 5 years ago

ok,解决的话我会把 commit 直接关联到这里

问一下作者,这个组件是否可以用百度离线地图来做?需要注意什么

xiaogaofudao commented 5 years ago

这是一个问题 https://github.com/Dafrok/vue-baidu-map/issues/590

我有个思路不知道准确不。当动态删减的时候,地图渲染的元素看着是正确的。当时 bm-marker 没有 监听 destroyed。销毁没有同时在 百度 销毁相关的东西,比如事件什么的。具体需要大神看下了。这个bug 还是比较长见的。特别是动态生成 marker。还需要动态删减的时候。

Dafrok commented 5 years ago

谢谢 @xiaogaofudao 的建议,我 check 下

xiaogaofudao commented 5 years ago

怎么样了啊。我刚把你的源码放到 项目里面。测试发现 bindEvent.js 的问题。 listener && instance.addEventListener(event, listener.fns); 改为 listener && instance.addEventListener(event, listener); 就可以了。不清楚 .fns 的具体作用。click 事件 .fns 是 undefined。其他事件未测

xiaogaofudao commented 5 years ago

目前marker 我只用到了 click 事件。通过修改 marker.vue 的绑定事件暂时修复 // bindEvents.call(this, overlay) if (this.$listeners.click) { overlay.addEventListener("click", this.$listeners.click); }

wangjunfeng1991 commented 5 years ago

用以下方法可以解决,之前我也被这个问题困扰很久,后来尝试了一下,发现在点击事件中传入index下标,再在回调中取markers集合对应下标,即可拿到当前marker的所有信息了。。。大致贴一下代码

<bm-marker v-for="(marker,index) in markers" :key="index" :position="{lng: markers[index].lng, lat: markers[index].lat}" :rotation="getRotation(markers[index].azimuth)" :icon="getIcon(markers[index].type, markers[index].isCenter)" :zIndex="zIndex" :offset="getOffsetData(markers[index].azimuth)" @click="showInfoWindow(index)">

infoWindowOpen (index) { var that=this; var e=that.markList[index]; that.infoPoints.lng = e.lng; that.infoPoints.lat = e.lat; var point = new BMap.Point(e.lng, e.lat); var myGeo = new BMap.Geocoder(); // 根据坐标得到地址描述 myGeo.getLocation(point, function (result) { e.location = result.address; that.infoData.lat=e.lat; that.infoData.lng=e.lng; that.infoData.icon=e.icon; that.infoData.speed=e.speed; that.infoData.location=e.location; that.infoData.time=e.time; that.isShow = true; }); },