React-Leaflet:将地图控制组件放置在地图之外?

2024-04-03

这是我的其他问题的更普遍的版本:从反应传单中的地图中删除缩放控制 https://stackoverflow.com/questions/59432189/remove-zoom-control-from-map-in-react-leaflet。 React-leaflet 附带了一些控制地图的组件 - 即<ZoomControl />, <LayersControl />等等。但是为了使这些组件能够与地图实例正确通信,它们必须被编写为<Map />组件,像这样:

<Map center={...} zoom={...}>

  <ZoomControl />
  <LayersControl />
  <MyCustomComponent />

</Map>

我试图创建一种情况,即不是地图直接子级的地图组件可以与地图正确通信。例如:

<App>
  <Map />
  <Sibling>
    <Niece>
      <ZoomControl />
      <OtherControls />
    </Niece>
  </Sibling>
</App>

显然这里的问题是当这些控件不再是子控件或后代控件时<Map />,他们不通过提供者接收地图实例。正如你所看到的我的另一个问题 https://stackoverflow.com/questions/59432189/remove-zoom-control-from-map-in-react-leaflet,我尝试创建一个新的 Context 对象并使用它为移位的控件提供地图。那没有用,我不知道为什么。到目前为止,我的解决方案是使用 vanilla javascript 将这些控件重新放置在componentDidMount他们的预期父母,如下所示:

// Niece.js
componentDidMount(){
  const newZoomHome = document.querySelector('#Niece')
  const leafletZoomControl= document.querySelector('.leaflet-control-zoom')
  newZoomHome.appendChild(leafletZoomControl)
}

我真的很讨厌这个,因为现在我的通用组件结构不反映应用程序结构。我的 Zoom 需要编写为地图的一部分,但最终会出现在我的 Neice 组件中。

Kboul 在我的另一个问题中的解决方案只是从头开始重建缩放组件并为其提供地图上下文。这对于简单的缩放组件来说效果很好,但对于更复杂的组件,我无法重建整个框架。例如,我制作了一个快速的react-leaflet组件版本Esri-leaflet 的地理搜索 https://esri.github.io/esri-leaflet/api-reference/controls/geosearch.html:

import { withLeaflet, MapControl } from "react-leaflet";
import * as ELG from "esri-leaflet-geocoder";

class GeoSearch extends MapControl {
  createLeafletElement(props) {
    const searchOptions = {
       ...props,
      providers: props.providers ? props.providers.map( provider => ELG[provider]()) : null
    };

    const GeoSearch = new ELG.Geosearch(searchOptions);
    // Author can specify a callback function for the results event
    if (props.onResult){
      GeoSearch.addEventListener('results', props.onResult)
    }
    return GeoSearch;
  }

  componentDidMount() {
    const { map } = this.props.leaflet;
    this.leafletElement.addTo(map);
  }
}

export default withLeaflet(GeoSearch);

它相对简单并且在内部声明时效果很好<Map />成分。但我想将其移动到应用程序中的单独位置,并且我不想重新编码整个 esri Geosearch。我如何在外部使用功能性的react-leaflet控制组件<Map />组件同时将其正确链接到地图实例?

这是一个快速代码沙箱模板 https://codesandbox.io/s/react-leaflet-context-question-e4jut如果你愿意的话就开始搞乱吧。谢谢阅读。


您可以使用onAdd https://leafletjs.com/reference-1.6.0.html#layer-onadd方法在地图之外为插件创建一个容器,然后使用 refs 将元素添加到 DOM,如下所示:

class Map extends React.Component {
  mapRef = createRef();
  plugin = createRef();

  componentDidMount() {
    // map instance
    const map = this.mapRef.current.leafletElement;

    const searchcontrol = new ELG.Geosearch();
    const results = new L.LayerGroup().addTo(map);
    searchcontrol.on("results", function(data) {
      results.clearLayers();
      for (let i = data.results.length - 1; i >= 0; i--) {
        results.addLayer(L.marker(data.results[i].latlng));
      }
    });
    const searchContainer = searchcontrol.onAdd(map);
    this.plugin.current.appendChild(searchContainer);
  }

  render() {
    return (
      <>
        <LeafletMap
          zoom={4}
          style={{ height: "50vh" }}
          ref={this.mapRef}
          center={[33.852169, -100.5322]}
        >
          <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
        </LeafletMap>
        <div ref={this.plugin} />
      </>
    );
  }
}

Demo https://codesandbox.io/s/react-leaflet-placing-map-control-components-outside-of-map-fw69g

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React-Leaflet:将地图控制组件放置在地图之外? 的相关文章

随机推荐