使用文本字段同时过滤react-table和react-leaflet标记(在表中显示过滤器数据并在地图中显示标记) [英] Filter react-table and react-leaflet marker at the same time using textfield (Show filter data in table and marker in the map)

查看:110
本文介绍了使用文本字段同时过滤react-table和react-leaflet标记(在表中显示过滤器数据并在地图中显示标记)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来的反应传单.需要一点帮助来解决我的问题.跟进上一篇文章

I am new to react-leaflet. Need little help to fix my issue. Follow up with Previous post

我有用于过滤数据的文本字段.我能够过滤表中的数据,但无法过滤地图中的数据. 例如:如果我搜索名称:"VaiBike",它应显示在表格中并显示在地图中.注意:仅在地图和表格中显示要过滤的数据.其他数据也是如此.

I have textfield which filter data. I was able to filter data in the table but not able to filter the data in the map. For example: if I search for name: 'VaiBike' it should show in table and marker in the map. Note: only show the data which is filter in map as well as in the table. so does for the other data.

如何更改代码,以便可以同时在表中显示标记和数据.

How can I change my code so that I can show marker and data in table at the same time.

运行代码

import React, { Component } from 'react'
    import { Map, TileLayer, Marker, Popup } from 'react-leaflet'
    import './style.css'
    import 'leaflet/dist/leaflet.css'
    import L from 'leaflet'
    import icon from 'leaflet/dist/images/marker-icon.png'
    import iconShadow from 'leaflet/dist/images/marker-shadow.png'
    import TextField from '@material-ui/core/TextField'
    // Import React Table
    import ReactTable from 'react-table'
    import 'react-table/react-table.css'
    import matchSorter from 'match-sorter'

    var myIcon = L.icon({
      iconUrl:
        'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAFgUlEQVR4Aa1XA5BjWRTN2oW17d3YaZtr2962HUzbDNpjszW24mRt28p47v7zq/bXZtrp/lWnXr337j3nPCe85NcypgSFdugCpW5YoDAMRaIMqRi6aKq5E3YqDQO3qAwjVWrD8Ncq/RBpykd8oZUb/kaJutow8r1aP9II0WmLKLIsJyv1w/kqw9Ch2MYdB++12Onxee/QMwvf4/Dk/Lfp/i4nxTXtOoQ4pW5Aj7wpici1A9erdAN2OH64x8OSP9j3Ft3b7aWkTg/Fm91siTra0f9on5sQr9INejH6CUUUpavjFNq1B+Oadhxmnfa8RfEmN8VNAsQhPqF55xHkMzz3jSmChWU6f7/XZKNH+9+hBLOHYozuKQPxyMPUKkrX/K0uWnfFaJGS1QPRtZsOPtr3NsW0uyh6NNCOkU3Yz+bXbT3I8G3xE5EXLXtCXbbqwCO9zPQYPRTZ5vIDXD7U+w7rFDEoUUf7ibHIR4y6bLVPXrz8JVZEql13trxwue/uDivd3fkWRbS6/IA2bID4uk0UpF1N8qLlbBlXs4Ee7HLTfV1j54APvODnSfOWBqtKVvjgLKzF5YdEk5ewRkGlK0i33Eofffc7HT56jD7/6U+qH3Cx7SBLNntH5YIPvODnyfIXZYRVDPqgHtLs5ABHD3YzLuespb7t79FY34DjMwrVrcTuwlT55YMPvOBnRrJ4VXTdNnYug5ucHLBjEpt30701A3Ts+HEa73u6dT3FNWwflY86eMHPk+Yu+i6pzUpRrW7SNDg5JHR4KapmM5Wv2E8Tfcb1HoqqHMHU+uWDD7zg54mz5/2BSnizi9T1Dg4QQXLToGNCkb6tb1NU+QAlGr1++eADrzhn/u8Q2YZhQVlZ5+CAOtqfbhmaUCS1ezNFVm2imDbPmPng5wmz+gwh+oHDce0eUtQ6OGDIyR0uUhUsoO3vfDmmgOezH0mZN59x7MBi++WDL1g/eEiU3avlidO671bkLfwbw5XV2P8Pzo0ydy4t2/0eu33xYSOMOD8hTf4CrBtGMSoXfPLchX+J0ruSePw3LZeK0juPJbYzrhkH0io7B3k164hiGvawhOKMLkrQLyVpZg8rHFW7E2uHOL888IBPlNZ1FPzstSJM694fWr6RwpvcJK60+0HCILTBzZLFNdtAzJaohze60T8qBzyh5ZuOg5e7uwQppofEmf2++DYvmySqGBuKaicF1blQjhuHdvCIMvp8whTTfZzI7RldpwtSzL+F1+wkdZ2TBOW2gIF88PBTzD/gpeREAMEbxnJcaJHNHrpzji0gQCS6hdkEeYt9DF/2qPcEC8RM28Hwmr3sdNyht00byAut2k3gufWNtgtOEOFGUwcXWNDbdNbpgBGxEvKkOQsxivJx33iow0Vw5S6SVTrpVq11ysA2Rp7gTfPfktc6zhtXBBC+adRLshf6sG2RfHPZ5EAc4sVZ83yCN00Fk/4kggu40ZTvIEm5g24qtU4KjBrx/BTTH8ifVASAG7gKrnWxJDcU7x8X6Ecczhm3o6YicvsLXWfh3Ch1W0k8x0nXF+0fFxgt4phz8QvypiwCCFKMqXCnqXExjq10beH+UUA7+nG6mdG/Pu0f3LgFcGrl2s0kNNjpmoJ9o4B29CMO8dMT4Q5ox8uitF6fqsrJOr8qnwNbRzv6hSnG5wP+64C7h9lp30hKNtKdWjtdkbuPA19nJ7Tz3zR/ibgARbhb4AlhavcBebmTHcFl2fvYEnW0ox9xMxKBS8btJ+KiEbq9zA4RthQXDhPa0T9TEe69gWupwc6uBUphquXgf+/FrIjweHQS4/pduMe5ERUMHUd9xv8ZR98CxkS4F2n3EUrUZ10EYNw7BWm9x1GiPssi3GgiGRDKWRYZfXlON+dfNbM+GgIwYdwAAAAASUVORK5CYII=',
      iconSize: [25, 41],
      iconAnchor: [12.5, 41],
      popupAnchor: [0, -41],
    })
    let DefaultIcon = L.icon({
      iconUrl: icon,
      shadowUrl: iconShadow,
    })

    L.Marker.prototype.options.icon = DefaultIcon

    export default class App extends Component {
      constructor(props) {
        super(props)
        this.state = {
        location: {
          lat: 51.505,
          lng: -0.09,
          filterAll: '',
        },
        bikeData: [],
        haveUsersLocation: false,
        zoom: 3,
      }
      }
      //lifecycle method to get the bike information
      componentDidMount() {
        fetch('https://api.citybik.es/v2/networks')
          .catch(error => {
            console.log(error)
          })
          .then(res => res.json())
          .then(response => {
            const networkData = response.networks
            this.setState({
              bikeData: networkData,
            })
          })
      }
      filterAll = e => {
        const { value } = e.target
        const filterAll = value
        const filtered = [{ id: 'all', value: filterAll }]
        const filterdMap =[{id:'bikeData', value: filterAll}]
        this.setState({ filterAll, filtered ,filterdMap})
      }

      render() {
        const position = [this.state.location.lat, this.state.location.lng]
        const bikeData = this.state.bikeData
        return (
          <div
            style={{
              height: '100vh',
            }}
            id="map"
          >
            <div align="right">
              <form noValidate autoComplete="off">
                <TextField
                  id="row"
                  label="Search Bike"
                  margin="normal"
                  value={this.state.filterAll}
                  onChange={this.filterAll}
                />
              </form>
            </div>
            <Map className="map" center={position} zoom={this.state.zoom}>
              <TileLayer
                attribution="&amp;copy <a href=&quot;http://osm.org/copyright&quot;>OpenStreetMap</a> contributors"
                url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
              />
              {bikeData &&
                bikeData.map(data => {
                  console.log(data)
                  return (
                    <Marker
                      icon={myIcon}
                      key={data.id}
                      position={[data.location.latitude, data.location.longitude]}
                    >
                      <Popup>
                        Name: {data.name} <br />
                        Station Details:{' '}
                        {[data.location.city, data.location.country]}
                      </Popup>
                    </Marker>
                  )
                })}
            </Map>
            <div>
              <ReactTable
                filtered={this.state.filtered}
                defaultFilterMethod={(filter, row) =>
                  String(row[filter.id]) === filter.value
                }
                data={bikeData}
                columns={[
                  {
                    columns: [
                      {
                        Header: ' Name',
                        accessor: 'name',
                        filterAll: true,
                      },

                      {
                        Header: '',
                        id: 'all',
                        width: 0,
                        resizable: false,
                        sortable: false,
                        Filter: () => {},
                        getProps: () => {
                          return {}
                        },
                        filterMethod: (filter, rows) => {
                          const result = matchSorter(rows, filter.value, {
                            keys: ['name'],
                            threshold: matchSorter.rankings.WORD_STARTS_WITH,
                          })

                          return result
                        },
                        filterAll: true,
                      },
                    ],
                  },
                ]}
                defaultPageSize={10}
              />
              <br />
            </div>
          </div>
        )
      }
    }

非常感谢您提供运行代码的帮助. 预先感谢.

Help with running code highly appreciated. Thanks in advance.

推荐答案

如果我正确理解了您的问题,则需要对代码进行一些调整.首先,添加状态以跟踪已过滤的自行车数据"(即,用户界面中用户可见的数据).您可以通过在构造函数中添加以下内容来做到这一点:

If I understand your question correctly, you'll need to make a few adjustments to your code. First, add state to track the "filtered bike data" (ie the data that is visible to users in the UI). You can do so by adding something like this in your constructor:

constructor(props) {
    super(props)
    this.state = {
    location: {
      lat: 51.505,
      lng: -0.09,
      filterAll: '',
    },
    bikeData: [],
    filteredBikeData : [], // Add this
    haveUsersLocation: false,
    zoom: 3,
  }
  }

现在,在filterAll所有文本字段更改处理程序中,您将要基于当前字段值更新filteredBikeData状态.您可以执行以下操作:

Now, in you filterAll all text field change handler, you'll want to update the filteredBikeData state based on the current field value. You can do so with something as follows:

filterAll = e => {
    const { value } = e.target

    // Get a filtered list of bikes based on original list
    const filteredBikes = this.state.bikeData.filter(bike => {

        // Filter bikes by name. Use toLowerCase to avoid case sensitivity issues
        return bike.name.toLowerCase().indexOf(value.toLowerCase()) !== -1
    })

    const filterAll = value
    const filtered = [{ id: 'all', value: filterAll }]
    const filterdMap =[{id:'bikeData', value: filterAll}]

    // Update state to include filtered bikes array
    this.setState({ filterAll, filtered ,filterdMap, filteredBikes})
}

最后,您需要基于过滤后的自行车阵列来渲染标记-像这样更新渲染方法:

Finally, you'll want to render markers based on the filtered array of bikes - update your render method like so:

{ /* use filteredBikes instead of bikes */
{ this.state.filteredBikes && this.state.filteredBikes.map(data => {
    console.log(data)
    return (
    <Marker
        icon={myIcon}
        key={data.id}
        position={[data.location.latitude, data.location.longitude]}
    >
        <Popup>
        Name: {data.name} <br />
        Station Details:{' '}
        {[data.location.city, data.location.country]}
        </Popup>
    </Marker>
    )
})}

另外,您可能还想将filteredBikes的值默认为从服务器获得的响应,以便用户最初在屏幕上看到一些内容:

As an extra, you might also want to default the value of filteredBikes to the response that you get from the server, so that the user initially sees something on screen:

componentDidMount() {
    fetch('https://api.citybik.es/v2/networks')
      .catch(error => {
        console.log(error)
      })
      .then(res => res.json())
      .then(response => {
        const networkData = response.networks
        this.setState({
          bikeData: networkData,
          filteredBikeData : networkData // Add this
        })
      })
  }

这篇关于使用文本字段同时过滤react-table和react-leaflet标记(在表中显示过滤器数据并在地图中显示标记)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆