Vue Google Maps Infowindow пользовательские кнопки не работают - PullRequest
0 голосов
/ 22 ноября 2018

Привет, vue-ers!

Я использую vue2-google-maps со всей его славой, и до сих пор мне удалось многое, кроме пользовательских кнопок в информационном окне.Пока я могу нажать на маркер, и он показывает соответствующее пользовательское информационное окно с правильной информацией.Единственное, чего мне не хватает сейчас - заставить эти кнопки работать.Например, кнопка закрытия: я могу нажать на нее, и она говорит о методе компонента, но не закрывает его.Кнопка закрытия работает так же, как выбор маркеров, но в то же время это не так?Значения обновляются до false, но не обновляются на картах, пока я выбираю маркер, он обновляется как шарм.Так что я застрял здесь и в замешательстве, любая помощь, идеи и советы приветствуются!

Вот мой код для справки:

Шаблон

<gmap-map
    id="map"
    :center="center"
    :zoom=13
    :options="{
        disableDefaultUI: true,
        zoomControl: true,
        clickableIcons: true,
    }">

    <gmap-marker
        v-for="(location, index) in locations"
        :position="{lat: location.latitude, lng: location.longitude}"
        :icon="location.icon"
        :zone="location.zone"
        :jettyNumber="location.jettyNumber"
        :selected="location.selected"
        :zIndex="location.zIndex"
        @mouseover="mouseOverMarker(index)"
        @mouseout="mouseOutMarker(index)"
        @click="openInfoWindow(index)"
        :label="{
            text: location.jettyNumber.toString(),
            color: '#fff',
            fontSize: '13px',
            fontFamily: 'din_round_otbold'
        }">

        <gmap-info-window
            :opened="location.infoBoxOpen">
                <div class="infoWindow" style="width: 300px;">
                    <div id="dock-zone" :class="getZoneClass(location.zone)">{{ getZoneClassText(location.zone) }}</div>
                    <h2 id="infoWindow-location">{{ location.name }}</h2>
                    <div id="close-btn" @click="closeInfoWindow(index)"></div>
                    <a class="btn btn-primary google-maps-infowindow-button">Kies als <b>{{ inputData.label }}</b></a>
                    <span></span>
                </div>
        </gmap-info-window>
    </gmap-marker>
</gmap-map>

Компонентный скрипт

import $ from "jquery";
export default {
data: function(){
    return {
        icons: {
            stopInner: {
                icon: process.env.VUE_APP_PUBLIC_URL + '/Assets/images/pinpoint_on_map_inner.svg'
            },
            stopOuter: {
                icon: process.env.VUE_APP_PUBLIC_URL + '/Assets/images/pinpoint_on_map_outer.svg'
            },
            stopOutside: {
                icon: process.env.VUE_APP_PUBLIC_URL + '/Assets/images/pinpoint_on_map_outside.svg'
            },
            stopSelected: {
                icon: process.env.VUE_APP_PUBLIC_URL + '/Assets/images/pinpoint_on_map_active.svg'
            }
        },
        locations: [],
        center: {lat: 51.9004, lng: 4.46849},
        inputData: {}
    };
},
methods: {
    initMap(locations, inputData) {
        // Set maps specific data
        for(var i = 0; i < locations.length; i++) {
            locations[i].selected = false;
            locations[i].infoBoxOpen = false;
            locations[i].zIndex = locations[i].jettyNumber;
            locations[i].icon = this.getIcon(locations[i].zone);
        }
        this.inputData = inputData;
        this.locations = locations;
    },
    getIcon(zone) {
        switch(zone){
            case "centre":
                return this.icons.stopInner.icon;
            break;
            case null:
                return this.icons.stopOutside.icon;
            break;
            default:
                return this.icons.stopOuter.icon;
            break;
        }
    },
    getZoneClass(zone) {
        switch(zone){
            case "centre":
                return "centrum";
            break;
            case null:
                return "buiten";
            break;
            default:
                return "";
            break;
        }
    },
    getZoneClassText(zone) {
        if(zone){
            return zone;
        }else{
            return "outside";
        }
    },
    // TODO: Not really setting the zindex, need to dig deeper
    mouseOverMarker(locationIndex) { 
        this.locations[locationIndex].zIndex = 99998;
    },
    mouseOutMarker(locationIndex) { 
        this.locations[locationIndex].zIndex = this.locations[locationIndex].jettyNumber; 
    },
    openInfoWindow(location){
        this.center = {lat: location.latitude, lng: location.longitude};
        this.setSelectedLocation(location);
    },
    setSelectedLocation(selectedLocationIndex){
        this.unselectLocations();
        // Set selected
        this.locations[selectedLocationIndex].zIndex = 88888;
        this.locations[selectedLocationIndex].icon = this.icons.stopSelected.icon;
        this.locations[selectedLocationIndex].selected = true;
        this.locations[selectedLocationIndex].infoBoxOpen = true;
        this.center = {
            lat: this.locations[selectedLocationIndex].latitude,
            lng: this.locations[selectedLocationIndex].longitude
        };
        this.alterDefaultInfoWindowStyle();
    },
    unselectLocations() {
        for(var i = 0; i < this.locations.length; i++) {
            this.locations[i].icon = this.getIcon(this.locations[i].zone);
            this.locations[i].zIndex = this.locations[i].jettyNumber;
            this.locations[i].selected = false;
            this.locations[i].infoBoxOpen = false;
        }
    },
    alterDefaultInfoWindowStyle() {
        // TODO: a very nasty fix, need a better way to handle this
        setTimeout(function(){
            var iwOuter = $('.gm-style-iw');
            iwOuter.parent().parent().css({ top: '20px' });
            iwOuter.css({ top: '0px' });
            iwOuter.css({ left: '26px' });

            var iwBackground = iwOuter.prev();
            iwBackground.css({ 'display': 'none' });
            var iwCloseBtn = iwOuter.next();

            iwCloseBtn.hide();
            iwOuter.children().eq(0).css({ overflow: 'visible' });
        }, 10);
    },
    closeInfoWindow(selectedLocationIndex) {
        this.unselectLocations();
    },
    closeMaps() {
        this.$emit('close-maps')
    }
}

}

1 Ответ

0 голосов
/ 03 января 2019

Поскольку внешний вид информационного окна определяется locations[index].infoBoxOpen, необходимо также реализовать стандартный обработчик закрытия (@closeclick), например:

 <gmap-info-window
        :opened="location.infoBoxOpen"
        @closeclick="location.infoBoxOpen=false">
    ...
 </gmap-info-window>  

Я бы также предложил изменитьспособ создания информационного окна.Вместо создания информационного окна для каждого маркера, нужно создать только один экземпляр информационного окна.В дополнение к преимуществам производительности было бы более понятно управлять состоянием информационного окна, например:

<gmap-map :center="center" :zoom="zoom" ref="map">
  <gmap-marker
    :key="index"
    v-for="(location,index) in locations"
    :position="{lat: location.lat,lng:location.lng}"
    :clickable="true"
    @click="openInfoWindow(location)"
  />
  <gmap-info-window v-if="selectedLocation !== null" :position="{lat: selectedLocation.lat,lng:selectedLocation.lng}" :opened="infoBoxOpen" @closeclick="closeInfoWindow()">
      <div class="infoWindow">
        <h2 id="infoWindow-location">{{ selectedLocation.name }}</h2>
        <button @click="closeInfoWindow()">Close</button>
      </div>
    </gmap-info-window>
</gmap-map>

export default {
  data: () => ({
    zoom: 5,
    center: { lat: 59.339025, lng: 18.065818 },
    selectedLocation: null,
    infoBoxOpen: false,
    locations: [
      {
        Id: 1,
        name: "Oslo",
        lat: 59.923043,
        lng: 10.752839
      },
      {
        Id: 2,
        name: "Stockholm",
        lat: 59.339025,
        lng: 18.065818
      },
      {
        Id: 3,
        name: "Copenhagen",
        lat: 55.675507,
        lng: 12.574227
      },
      {
        Id: 4,
        name: "Berlin",
        lat: 52.521248,
        lng: 13.399038
      },
      {
        Id: 5,
        name: "Paris",
        lat: 48.856127,
        lng: 2.346525
      }
    ]
  }),
  methods: {
    openInfoWindow(location) {
      this.selectedLocation = location
      this.infoBoxOpen = true;
    },
    closeInfoWindow() {
      this.infoBoxOpen = false;
    }
  }
};    

Вот демонстрационная версия , которая демонстрирует, как управлять информационным окном для нескольких маркеров

...