繁体   English   中英

我正在尝试将 react-bootstrap 手风琴绑定到 Leaflet.js 标记。 单击手风琴时,标记将放大

[英]i'm trying to bind react-bootstrap accordion to a leaflet.js marker. when clicking on accordion, marker will get zoomed-in

我正在尝试将 react-bootstrap 手风琴绑定到 Leaflet.js 标记。 单击手风琴时,标记将被放大...问题是我必须在手风琴上“双击”以折叠它并放大标记 => 因为在关注标记时手风琴正在刷新

**代码沙盒演示**

https://codesandbox.io/s/react-leaflet-with-imageoverlay-add-remove-markers-dynamically-2tmex

地图容器

 import React, { useEffect, useState } from "react"; import "leaflet/dist/leaflet.css"; import L from "leaflet"; import masterplan from "./img/masterplan.jpg"; let map; const markerIcon = 'https://www.pinclipart.com/picdir/big/141-1410207_marker-filled-icon-location-logo-png-file-clipart.png' const editMarkerIcon = 'https://cdn.iconscout.com/icon/premium/png-256-thumb/marker-1829264-1551716.png' var myIcon = L.icon( { iconUrl: markerIcon, iconSize: [ 30, 35 ], iconAnchor: [ 15, 35 ], popupAnchor: [ 0, -40 ], } ); var editMyIcon = L.icon( { iconUrl: editMarkerIcon, iconSize: [ 50, 40 ], iconAnchor: [ 25, 35 ], popupAnchor: [ 0, -40 ], } ); const MapContainer = ( { data, linkName, formCss, addMarker, isMarkerAdded, setIsMarkerAdded, formData, setFormData, setGetMarkerObject, setMarkersList, setEdit, clicked, setClicked } ) => { const [ coordinates, setCoordinates ] = useState( { lats: 0, lngs: 0 } ) // setting up the map with the image inside const MaxMapMBounds = [ [ 0.047356142676201576, -0.05648240856298255 ], [ -0.09911669921875, 0.05903846615873286 ] ] // building the map container const buildMap = () => { map = L.map( 'map', { crs: L.CRS.Simple, maxBounds: MaxMapMBounds, minZoom: 13, maxZoom: 15, maxBoundsViscosity: 0.0, } ).setView( [ 0, 0 ], 13 ); // rendering the image inside the map var imageBounds = [ [ 0.0484693481114499, -0.0652342559975141 ], [ -0.03143095517869242, 0.06518541415112039 ] ]; const image = L.imageOverlay( masterplan, imageBounds, { className: 'image-map' }, ).addTo( map ); // Logging coordinates when clicking on the map map.on( 'click', function ( e ) { var coord = e.latlng; var lat = coord.lat; var lng = coord.lng; console.log( `latitude: ${ lat } and longitude: ${ lng } === [${ lat } , ${ lng } ]` ); } ); return map } useEffect( () => { buildMap() addMarkers() renderMarkers() return () => { map.off(); map.remove(); } }, [ data, ] ); // // adding markers from FormMarker with draggable markers available const addMarkers = ( editedMarkerLatLng ) => { if ( addMarker ) { let marker; // adding markers if ( isMarkerAdded === false ) { let onDrag = function ( e ) { let latlng = marker.getLatLng(); setCoordinates( { lats: latlng.lat, lngs: latlng.lng } ) setFormData( { ...formData, coordinates: [ latlng.lat, latlng.lng ] } ) // showing popup when dragging marker.bindPopup().openPopup() }; let onClick = function ( e ) { setIsMarkerAdded( true ) map.off( 'click', onClick ); //turn off listener for map click marker = L.marker( e.latlng, { icon: editMyIcon, draggable: true } ).addTo( map ).bindPopup( '<p>انا هنا يا جون</p>', { closePopupOnClick: false, autoClose: false, closeOnClick: false, } ).openPopup(); // updating coordinates <p> on the ui setCoordinates( { lats: e.latlng.lat, lngs: e.latlng.lng } ) // updating coordinates on the form setFormData( { ...setFormData, coordinates: [ e.latlng.lat, e.latlng.lng ] } ) marker.on( 'drag', onDrag ); // removing popup after adding the marker to markersList setGetMarkerObject( marker ) }; map.on( 'click', onClick ); } } } // rendering Markers of the Units inside the map &&& Focusing on selected unit by touching on its button link const renderMarkers = () => { data && data.map( ( link ) => { let marker if ( addMarker ) { // rendering markers at add-marker page var container = L.DomUtil.create( 'div' ); const createButton = ( label, container, className ) => { var btn = L.DomUtil.create( 'button', '', container ); btn.setAttribute( 'type', 'button' ); btn.setAttribute( 'class', className ); btn.innerHTML = label; return btn; } const createParagraph = ( label, container, className ) => { var para = L.DomUtil.create( 'p', '', container ); para.setAttribute( 'class', className ); para.innerHTML = label; return para; } const editButton = createButton( 'Edit marker', container, 'edit-button' ); const removeButton = createButton( 'Remove marker', container, 'remove-button' ); const popupText = createParagraph( `Name: ${ link.name }`, container, 'popup-text' ) L.DomEvent.on( editButton, 'click', () => handleEditMarker( marker ) ); L.DomEvent.on( removeButton, 'click', () => handleRemoveMarker( marker ) ); return marker = L.marker( L.latLng( link.markerPosition ), { icon: myIcon } ).addTo( map ).bindPopup( container ) } // rendering markers at home page marker = L.marker( L.latLng( link.markerPosition ), { icon: myIcon } ).addTo( map ).bindPopup( link.markerText ) if ( link.name === linkName ) { // Focusing on selected unit by touching on its button link let unitMarker = L.polygon( link.latlng, { fill: false, opacity: 0 } ).addTo( map ) marker.openPopup() map.fitBounds( unitMarker.getBounds() ) // setClicked( true ) } } ) } const handleEditMarker = ( marker ) => { setIsMarkerAdded( true ) setEdit( true ) const lat = marker._latlng.lat const lng = marker._latlng.lng let editedMarker = data.find( item => item.markerPosition[ 0 ] === lat && item.markerPosition[ 1 ] === lng ) handleRemoveMarker( marker ) setFormData( { ...editedMarker, coordinates: [ lat, lng ] } ) marker = L.marker( [ lat, lng ], { icon: editMyIcon, draggable: true } ).addTo( map ).bindPopup( '<p>انا هنا يا جون</p>', { closePopupOnClick: false, autoClose: false, closeOnClick: false, } ).openPopup(); let onDrag = function ( e ) { let latlng = marker.getLatLng(); // setCoordinates( { lats: latlng.lat, lngs: latlng.lng } ) setFormData( { ...editedMarker, coordinates: [ latlng.lat, latlng.lng ] } ) // showing popup when dragging marker.bindPopup().openPopup() }; marker.on( 'drag', onDrag ); setGetMarkerObject( marker ) } const handleRemoveMarker = ( marker ) => { const lat = marker._latlng.lat const lng = marker._latlng.lng let tempMarkers = data.filter( item => item.markerPosition[ 0 ] !== lat && item.markerPosition[ 1 ] !== lng ) setMarkersList( tempMarkers ) } return ( <div className={ formCss ? 'map-container-form' : 'map-container' }> <div id="map" ></div> { formCss && <p>coordinates: { `[ ${ coordinates.lats }, ${ coordinates.lngs } ]` }</p> } </div> ); }; export default MapContainer
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

手风琴组件

 import React, { useEffect } from 'react' import { Accordion, useAccordionButton } from 'react-bootstrap'; import 'bootstrap/dist/css/bootstrap.min.css'; const AccordionComp = ( { link, handleLink } ) => { return ( <Accordion.Item eventKey={ link.id } onClick={ ( e ) => { handleLink( e, link.name ) } } > <Accordion.Header > { link.name } </Accordion.Header> <Accordion.Body> <p><b> Type: </b>{ link.type }</p> <p><b> Area: </b>{ link.area } ( ㎡ )</p> <p><b> Price: </b> { link.price } (LE)</p> <p><b> Description: </b> { link.description }</p> </Accordion.Body> </Accordion.Item> ) } export default AccordionComp
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

应用组件

**问题是当我点击手风琴时,'handleLink' fn 被调用以使用 setLinkName 更新 linkName 状态......当我注释掉 setLinkName fn => 手风琴从第一次点击开始工作:( **

 import './App.css'; import React, { useState, useEffect } from 'react' import { data } from './data' import MapContainer from './MapContainer' import { Route, Switch } from "react-router-dom"; import FormMarker from './FormMarker'; import AccordionComp from './components/AccordionComp'; import { Accordion } from 'react-bootstrap'; const App = () => { const [ clicked, setClicked ] = useState( false ) const [ linkName, setLinkName ] = useState( null ) const initialMarkersList = localStorage.getItem( "markersList" ) ? JSON.parse( localStorage.getItem( "markersList" ) ) : []; const handleLink = ( e, linkName ) => { setLinkName( linkName ) } const Home = () => { return ( <div className="App"> <div className="links"> <Accordion > { initialMarkersList && initialMarkersList.map( ( link ) => { return <AccordionComp key={ link.id } link={ link } setLinkName={ setLinkName } handleLink={ handleLink } setClicked={ setClicked } /> } ) } </Accordion> </div> <MapContainer data={ initialMarkersList } linkName={ linkName } clicked={ clicked } setClicked={ setClicked } /> </div> ) } useEffect( () => { console.log( document.getElementsByClassName( 'accordion-collapse' )[ 0 ].classList ); }, [] ) console.log( linkName, 'linkname' ); console.log( clicked, 'clickde' ); return ( <> <Switch> <Route path="/" exact component={ Home } /> <Route path="/add-marker" exact component={ FormMarker } /> </Switch > </> ) } export default App;
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

答案是将 App comp 中的状态和方法移动到 Home comp 中,它已经在 App comp 内

 import './App.css'; import React, { useState, useEffect } from 'react' import { data } from './data' import MapContainer from './MapContainer' import { Route, Switch } from "react-router-dom"; import FormMarker from './FormMarker'; import AccordionComp from './components/AccordionComp'; import { Accordion } from 'react-bootstrap'; const App = () => { const Home = () => { const [ clicked, setClicked ] = useState( false ) const [ linkName, setLinkName ] = useState( null ) const initialMarkersList = localStorage.getItem( "markersList" ) ? JSON.parse( localStorage.getItem( "markersList" ) ) : []; const handleLink = ( e, linkName ) => { setLinkName( linkName ) } return ( <div className="App"> <div className="links"> <Accordion > { initialMarkersList && initialMarkersList.map( ( link ) => { return <AccordionComp key={ link.id } link={ link } setLinkName={ setLinkName } handleLink={ handleLink } setClicked={ setClicked } /> } ) } </Accordion> </div> <MapContainer data={ initialMarkersList } linkName={ linkName } clicked={ clicked } setClicked={ setClicked } /> </div> ) } useEffect( () => { console.log( document.getElementsByClassName( 'accordion-collapse' )[ 0 ].classList ); }, [] ) console.log( linkName, 'linkname' ); console.log( clicked, 'clickde' ); return ( <> <Switch> <Route path="/" exact component={ Home } /> <Route path="/add-marker" exact component={ FormMarker } /> </Switch > </> ) } export default App; <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM