【问题标题】:Add parameters to MUI Google Maps Autocomplete向 MUI 谷歌地图自动完成添加参数
【发布时间】:2021-10-06 11:13:17
【问题描述】:

我对 React 还很陌生,并且刚刚开始按照 MUI 示例使用 Google Maps Autocomplete API。我希望自动完成功能仅提供地理编码结果,但无法确定在我的代码中添加参数的位置?

我已经研究了 Google 地图文档(老实说,我还没有深入了解)并了解它的工作原理,但不了解如何实施。

这是我的代码(与 MUI 示例完全相同):

import * as React from 'react';
import Box from '@mui/material/Box';
import TextField from '@mui/material/TextField';
import Autocomplete from '@mui/material/Autocomplete';
import LocationOnIcon from '@mui/icons-material/LocationOn';
import Grid from '@mui/material/Grid';
import Typography from '@mui/material/Typography';
import parse from 'autosuggest-highlight/parse';
import throttle from 'lodash/throttle';

function loadScript(src, position, id) {
  if (!position) {
    return;
  }

  const script = document.createElement('script');
  script.setAttribute('async', '');
  script.setAttribute('id', id);
  script.src = src;
  position.appendChild(script);
}

const autocompleteService = { current: null };

export default function GoogleMaps() {
  const [value, setValue] = React.useState(null);
  const [inputValue, setInputValue] = React.useState('');
  const [options, setOptions] = React.useState([]);
  const loaded = React.useRef(false);

  if (typeof window !== 'undefined' && !loaded.current) {
    if (!document.querySelector('#google-maps')) {
      loadScript(
        'https://maps.googleapis.com/maps/api/js?key=MY_KEY&libraries=places',
        document.querySelector('head'),
        'google-maps',
      );
    }

    loaded.current = true;
  }

  const fetch = React.useMemo(
    () =>
      throttle((request, callback) => {
        autocompleteService.current.getPlacePredictions(request, callback);
      }, 200),
    [],
  );

  React.useEffect(() => {
    let active = true;

    if (!autocompleteService.current && window.google) {
      autocompleteService.current =
        new window.google.maps.places.AutocompleteService();
    }
    if (!autocompleteService.current) {
      return undefined;
    }

    if (inputValue === '') {
      setOptions(value ? [value] : []);
      return undefined;
    }

    fetch({ input: inputValue }, (results) => {
      if (active) {
        let newOptions = [];

        if (value) {
          newOptions = [value];
        }

        if (results) {
          newOptions = [...newOptions, ...results];
        }

        setOptions(newOptions);
      }
    });

    return () => {
      active = false;
    };
  }, [value, inputValue, fetch]);

  return (
    <Autocomplete
      id="google-map-demo"
      sx={{ width: 300 }}
      getOptionLabel={(option) =>
        typeof option === 'string' ? option : option.description
      }
      filterOptions={(x) => x}
      options={options}
      autoComplete
      includeInputInList
      filterSelectedOptions
      value={value}
      onChange={(event, newValue) => {
        setOptions(newValue ? [newValue, ...options] : options);
        setValue(newValue);
      }}
      onInputChange={(event, newInputValue) => {
        setInputValue(newInputValue);
      }}
      renderInput={(params) => (
        <TextField {...params} label="Add a location" fullWidth />
      )}
      renderOption={(props, option) => {
        const matches = option.structured_formatting.main_text_matched_substrings;
        const parts = parse(
          option.structured_formatting.main_text,
          matches.map((match) => [match.offset, match.offset + match.length]),
        );

        return (
          <li {...props}>
            <Grid container alignItems="center">
              <Grid item>
                <Box
                  component={LocationOnIcon}
                  sx={{ color: 'text.secondary', mr: 2 }}
                />
              </Grid>
              <Grid item xs>
                {parts.map((part, index) => (
                  <span
                    key={index}
                    style={{
                      fontWeight: part.highlight ? 700 : 400,
                    }}
                  >
                    {part.text}
                  </span>
                ))}

                <Typography variant="body2" color="text.secondary">
                  {option.structured_formatting.secondary_text}
                </Typography>
              </Grid>
            </Grid>
          </li>
        );
      }}
    />
  );
}

谢谢!

【问题讨论】:

    标签: reactjs google-maps material-ui googleplacesautocomplete


    【解决方案1】:

    为此,您可以在调用 getPlacePredictions 之前将 componentRestrictions 添加到 React useMemo 挂钩中的请求对象。例如,在您的代码中使用下面的 sn-p 将结果限制在澳大利亚

    const fetch = React.useMemo(
        () =>
          throttle((request, callback) => {
            request.componentRestrictions = {country: 'au'};
            autocompleteService.current.getPlacePredictions(request, callback);
          }, 200),
        [],
      );
    

    关于componentRestrictions的更多信息可以在Google Maps Platform docs中找到

    【讨论】:

    • 感谢您的帮助!我已经研究了您的解决方案并对其进行了一些尝试,但似乎无法使用它来仅通过此解决方案根据其类型过滤结果。我需要自动完成来只返回地理位置(国家或城市),而不提供公司、地址……
    猜你喜欢
    • 1970-01-01
    • 2012-11-21
    • 2016-11-17
    • 2018-01-26
    • 1970-01-01
    • 1970-01-01
    • 2017-03-15
    • 1970-01-01
    相关资源
    最近更新 更多