Открытое всплывающее окно при наведении мыши на список - PullRequest
0 голосов
/ 29 января 2019

Один вид моего приложения - список всех выводов на одной стороне и карта с фактическими выводами на другой стороне.

Я бы хотел, чтобы всплывающие окна открывались, когда я наводил курсор на список с помощью мыши.Допустим, моя мышь находится на # 1 в списке, я бы хотел, чтобы открылось всплывающее окно с соответствующим пин-кодом.

это HTML-код из компонента списка:

    <table class="table-striped">
      <thead>
        <!-- <th>id</th> -->
        <th>Kunstwerkname</th>
        <th>Strasse</th>
        <th>PLZ</th>
        <th>
          <button class="button-list" (click)="addArtwork()">
            <img src="assets/icons/add.svg">
          </button>
        </th>
      </thead>
      <tbody>
        <tr *ngFor="let artwork of artworkList;" class="artworkList" (mouseover)="previewPopup(artwork)">
          <td>{{artwork.name}}</td>
          <td>{{artwork.streetname}}</td>
          <td>{{artwork.zipcode}}</td>
          <td>
            <button class="button-list" (click)="editArtwork(artwork)">
              <img src="assets/icons/edit.svg">
            </button>
            <button class="button-list" (click)="deleteArtwork(artwork)">
              <img src="assets/icons/delete.svg">
            </button>
          </td>
        </tr>
      </tbody>
    </table>

TS компонента списка:

import { Artwork, ArtworkService } from './../_services/artwork.service';
import { Component, OnInit, Output, EventEmitter } from '@angular/core';


@Component({
  selector: 'app-artwork-list',
  templateUrl: './artwork-list.component.html',
  styleUrls: ['./artwork-list.component.css']
})
export class ArtworkListComponent implements OnInit {
  @Output() private add = new EventEmitter();
  @Output() private edit = new EventEmitter<number>();
  @Output() private preview = new EventEmitter<number>();
  artworkList: Artwork[];

  constructor(
    private artworkService: ArtworkService,
) { }

  ngOnInit() {
    this.refresh();
  }
  refresh() {
    this.artworkService.retrieveAll().then(
      artworkList => this.artworkList = artworkList
    );
  }

  addArtwork() {
    console.log('add artwork');
    this.add.emit();
  }

  editArtwork(artwork: Artwork) {
    console.log('edit artwork ' + artwork.name + ' ' + artwork.id );
    this.edit.emit(artwork.id);
  }

  deleteArtwork(artwork: Artwork) {
    console.log('delete artwork ' + artwork.name + ' ' + artwork.id );
    this.artworkService.delete(artwork.id).then(
      () => this.refresh()
    );
  }

  previewPopup(artwork: Artwork) {
    console.log("hovering mouse");
    console.log(artwork.id);
    this.preview.emit(artwork.id);
  }

}

и TS компонента карты:

import { Component, OnInit, Output, EventEmitter, ElementRef, Input } from '@angular/core';

/*When you include the leaflet script inside the Angular project, it gets
loaded and exported into a L variable.*/
declare let L; //this is the leaflet variable!

import { MapButtonsComponent } from './map-buttons/map-buttons';
import { Artwork, ArtworkService } from '../_services/artwork.service';
import { FilterMapComponent } from './filter-map/filter-map.component';



@Component({
  selector: 'app-open-street-map',
  templateUrl: './open-street-map.component.html',
  styleUrls: ['./open-street-map.component.css']
})
export class OpenStreetMapComponent implements OnInit {
  @Output() private add = new EventEmitter();
  @Output() private edit = new EventEmitter<number>();
  artworkList: Artwork[];
  map;

  // markerIcon
  markerIcon = {
    icon: L.icon({
      iconSize: [25, 41],
      iconAnchor: [13, 16],
      iconUrl: 'assets/icons/marker.svg',
      shadowUrl: 'assets/icons/marker-shadow.png'
    })
  };

  constructor(
    private artworkService: ArtworkService,
    private elementRef: ElementRef
  ) { }

  ngOnInit() {
    this.map = L.map('map', {
      center: [48.208, 16.373],
      zoom: 13,
      zoomControl: false,
    });

    this.refresh();

    // base layer
    L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
      attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
      maxZoom: 18,
      minZoom: 13,
      id: 'mapbox.streets',
      accessToken: 'pk.eyJ1IjoicHcxN2wwMDgiLCJhIjoiY2pua2c2OWxuMGVkOTNxbWh5MWNqajEwdyJ9.X_SuGwNGs12TwCsrsUvBxw'
    }).addTo(this.map);

    MapButtonsComponent.renderZoom(this.map);
    MapButtonsComponent.renderCompass(this.map);
    MapButtonsComponent.renderLocation(this.map);
  }

  previewArtwork() {
   this.map.eachLayer(layer => {
  if (layer instanceof L.Marker) {
    this.map.removeLayer(layer);
  }
});
let previewedMarker = L.marker([artwork.latitude, artwork.longitude], this.markerIcon)
  .addTo(this.map)
  .on('mouseover', () => {
    openPopup();
  });
}

  }
}

Ответы [ 2 ]

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

Можно рассмотреть следующий подход.Предположим, что исходные данные для маркеров представлены в следующем формате:

locations = [
    {
      name: "Oslo",
      lat: 59.923043,
      lng: 10.752839
    },
    {
      name: "Stockholm",
      lat: 59.339025,
      lng: 18.065818
    },
    //..
  ];

Тогда для заданных данных маркеры на карте могут быть инициализированы следующим образом:

this.markers = this.locations.map(loc => {
    const marker = new L.marker({ lat: loc.lat, lng: loc.lng });
    marker.bindPopup(loc.name);
    marker.addTo(map);
    return marker;
}); 

Теперь настала очередьсвязи между компонентом селектора и самой картой, давайте предположим, что выбран следующий селектор:

<ul>
  <li (mouseenter) ="mouseEnter(idx) "  (mouseleave) ="mouseLeave(idx)"  *ngFor="let loc of locations; let idx = index">{{ loc.name }}</li>
</ul>

, тогда видимость всплывающего окна можно контролировать следующим образом:

mouseEnter(selectedIndex) {
   const selectedMarker = this.markers[selectedIndex];
  selectedMarker.openPopup();
}

mouseLeave(selectedIndex) {
   const selectedMarker = this.markers[selectedIndex];
   selectedMarker.closePopup();
}

Вот демонстрация

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

Вместо использования mouseover вы должны слушать mouseenter и mouseleave

На mouseenter вы создадите всплывающее окно и поместите его на карту, на mouseleave вы закроетевсплывающее окно

Пример кода с помощью jQuery (мой postContent соответствует вашему произведению)

$("div.postContent").on("mouseenter", function(e) {
        var postId = $(this).attr("data-postId");

        tooltipPopup = L.popup();   
        var title = postlistByGlobalId[postId].title;
        tooltipPopup.setContent(title);
        tooltipPopup.setLatLng(markersByGlobalId[postId].getLatLng());
        tooltipPopup.openOn(map);

        $(this).addClass('hover');
    });

$("div.postContent").on("mouseleave", function(e) {
        $(this).removeClass('hover');
        map.closePopup(tooltipPopup);
    });

Для этого вам нужно дать уникальный идентификатор для всех ваших произведений (postId в моем примере) ипоместите ваши маркеры в ассоциативный массив markersByGlobalId

Это может быть полезно: http://franceimage.github.io/map и http://franceimage.github.io/map-v1

Мои примеры являются монолитными (1 html, 1 js file).Чтобы использовать его в своем приложении Angular, вам потребуется дополнительная работа.

...