מעבר לגרסה החדשה של ההשלמה האוטומטית למקומות

השלמה אוטומטית למקומות היא תכונה של ספריית המקומות ב-Maps JavaScript API. אתם יכולים להשתמש בהשלמה האוטומטית כדי לתת לאפליקציות שלכם את התנהגות החיפוש של שדה החיפוש במפות Google.

במאמר הזה נסביר את ההבדלים בין התכונות הקודמות לבין התכונות החדשות של השלמה אוטומטית של מקומות. בשתי הגרסאות יש שתי דרכים כלליות לשילוב השלמה אוטומטית:

ממשק פרוגרמטיבי להשלמה אוטומטית

בטבלה הבאה מפורטים חלק מההבדלים העיקריים בשימוש ב-Place Autocomplete באופן פרוגרמטי בין Places Autocomplete Service (ממשק ישן) לבין Autocomplete Data API (ממשק חדש):

PlacesService (דור קודם) Place (חדש)
מסמך עזרה בנושא השירות 'השלמה אוטומטית למקומות' מסמך העזרה בנושא נתוני השלמה אוטומטית (חדש)
AutocompletionRequest AutocompleteRequest
AutocompleteService.getPlacePredictions AutocompleteSuggestion.fetchAutocompleteSuggestions
AutocompletePrediction PlacePrediction
כדי לטפל באובייקט התוצאות ובתגובה PlacesServiceStatus, צריך להשתמש ב-method עם קריאה חוזרת. משתמשת ב-Promises ופועלת באופן אסינכרוני.
שיטות דורשות בדיקה של PlacesServiceStatus. אין צורך בבדיקת סטטוס, אפשר להשתמש בטיפול שגיאות רגיל.
שדות הנתונים של המיקום מוגדרים כאפשרויות כשיוצרים את המכונה של Autocomplete. שדות הנתונים של המיקום מוגדרים מאוחר יותר, כשמתבצעת קריאה ל-fetchFields().
יש תמיכה בתחזיות של שאילתות (SearchBox בלבד). תחזיות לשאילתות לא זמינות בכיתה Autocomplete.
מוגבלת לקבוצה קבועה של סוגים של מקומות ושדות של נתוני מקומות. גישה למבחר מורחב של סוגי מקומות ושדות של נתוני מקומות.

גם ממשקי ה-API הקודמים וגם החדשים של השלמה אוטומטית משתמשים בפרטים הבאים:

השוואת קוד (פרוגרמטית)

בקטע הזה נסביר על ההבדלים בין שירות Places לבין הכיתה Place, תוך השוואה של הקוד להשלמה האוטומטית לממשקים פרוגרמטיים.

אחזור של חיזויים להשלמה אוטומטית (מדור קודם)

שירות המקומות הקודם מאפשר לאחזר תחזיות להשלמה אוטומטית באופן פרוגרמטי, כדי לקבל יותר שליטה בממשק המשתמש מאשר בכיתה Autocomplete. בדוגמה הבאה, נשלחת בקשה אחת עבור 'par', עם AutocompletionRequest שמכיל את ערך הקלט וקבוצה של גבולות להטיה של התחזית. בדוגמה הזו מוצגת רשימה של מכונות AutocompletePrediction עם התיאור של כל אחת מהן. הפונקציה לדוגמה יוצרת גם אסימון סשן ומחילה אותו על הבקשה.

function init() {
  const placeInfo = document.getElementById("prediction");
  const service = new google.maps.places.AutocompleteService();
  const placesService = new google.maps.places.PlacesService(placeInfo);
  var sessionToken = new google.maps.places.AutocompleteSessionToken();

  // Define request options.
  let request = {
    input: "par",
    sessionToken: sessionToken,
    bounds: {
      west: -122.44,
      north: 37.8,
      east: -122.39,
      south: 37.78,
    },
  }

  // Display the query string.
  const title = document.getElementById("title");
  title.appendChild(
    document.createTextNode('Place predictions for "' + request.input + '":'),
  );

  // Perform the query and display the results.
  const displaySuggestions = function (predictions, status) {
    // Check the status of the Places Service.
    if (status != google.maps.places.PlacesServiceStatus.OK || !predictions) {
      alert(status);
      return;
    }

    predictions.forEach((prediction) => {
      const li = document.createElement("li");
      li.appendChild(document.createTextNode(prediction.description));
      document.getElementById("results").appendChild(li);
    });

    const placeRequest = {
      placeId: predictions[0].place_id,
      fields: ["name", "formatted_address"],
    };

    placesService.getDetails(placeRequest, (place, status) => {
      if (status == google.maps.places.PlacesServiceStatus.OK && place) {
        placeInfo.textContent = `
          First predicted place: ${place.name} at ${place.formatted_address}`
      }
    });

  };

  // Show the results of the query.
  service.getPlacePredictions(request, displaySuggestions);
}

אחזור של הצעות להשלמת החיפוש (חדש)

בנוסף, בכיתה החדשה Place אפשר לאחזר תחזיות להשלמה אוטומטית באופן פרוגרמטי, כדי לקבל שליטה רבה יותר בממשק המשתמש מאשר בכיתה PlaceAutocompleteElement. בדוגמה הבאה, נשלחת בקשה אחת עבור 'par', עם AutocompleteRequest שמכיל את ערך הקלט וקבוצה של גבולות להטיה של התחזית. בדוגמה הזו מוצגת רשימה של מכונות placePrediction עם התיאור של כל אחת מהן. הפונקציה לדוגמה יוצרת גם אסימון סשן ומחילה אותו על הבקשה.

async function init() {
  let sessionToken = new google.maps.places.AutocompleteSessionToken();

  // Define request options.
  let request = {
    input: "par",
    sessionToken: sessionToken,
    locationBias: {
      west: -122.44,
      north: 37.8,
      east: -122.39,
      south: 37.78,
    },
  };

  // Display the query string.
  const title = document.getElementById("title");
  title.appendChild(
    document.createTextNode('Place predictions for "' + request.input + '":'),
  );

  // Perform the query and display the results.
  const { suggestions } =
    await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(request);

  const resultsElement = document.getElementById("results");

  for (let suggestion of suggestions) {
    const placePrediction = suggestion.placePrediction;
    const listItem = document.createElement("li");

    listItem.appendChild(
      document.createTextNode(placePrediction.text.text),
    );

    resultsElement.appendChild(listItem);
  }

  // Show the first predicted place.
  let place = suggestions[0].placePrediction.toPlace();

  await place.fetchFields({
    fields: ["displayName", "formattedAddress"],
  });

  const placeInfo = document.getElementById("prediction");

  placeInfo.textContent = `
    First predicted place: ${place.displayName} at ${place.formattedAddress}`
}

הווידג'ט 'השלמה אוטומטית למקומות'

בטבלה הבאה מפורטים חלק מההבדלים העיקריים בשימוש בווידג'טים של השלמה אוטומטית בין שירות Places (מהדור קודם) לבין הכיתה Place (חדשה):

שירות Places (דור קודם) מקום (חדש)
בכיתה Autocomplete, לצורך חיזוי מקומות. בכיתה PlaceAutocompleteElement, לצורך חיזוי מקומות.
SearchBox class
לתחזיות של שאילתות.
תחזיות לשאילתות לא זמינות בכיתה Autocomplete.
רק טקסט placeholder של ברירת המחדל להזנה מתורגם. ה-placeholder להזנת טקסט, הלוגו של רשימת התחזיות והתחזיות למיקומים נתמכים בהתאמה לאזור.
הווידג'ט משתמש ב- setBounds() או ב-autocomplete.bindTo() כדי להגביל (לנטות) את החיפוש לגבולות שצוינו, וגם ב- strictBounds כדי להגביל את התוצאות לגבולות שצוינו. הווידג'ט משתמש במאפיין locationBias כדי להטות את התוצאות לגבולות שצוינו, ובמאפיין locationRestriction כדי להגביל את החיפוש לגבולות שצוינו.
אפשר לשלב ווידג'טים רק באמצעות רכיב קלט סטנדרטי של HTML. אפשר לשלב את הווידג'ט באמצעות רכיב קלט סטנדרטי של HTML או באמצעות רכיב gmp-place-autocomplete.
כשמשתמשים בווידג'ט, יכול להיות שמשתמשים יבקשו דברים שלא תקינים (לדוגמה, 'bisneyland'). במקרה כזה, צריך לטפל בבקשה באופן מפורש. הווידג'ט יחזיר תוצאות רק להצעות שסופקו, ולא יכול להנפיק בקשות לערכים שרירותיים. לכן אין צורך לטפל בבקשות שעשויות להיות לא חוקיות.
הפונקציה מחזירה מופע PlaceResult מדור קודם. הפונקציה מחזירה מופע של Place.
שדות הנתונים של המיקום מוגדרים כאפשרויות לאובייקט Autocomplete. שדות הנתונים של המיקום מוגדרים כשהמשתמש מבצע בחירה ומפעיל את fetchFields().
מוגבלת לקבוצה קבועה של סוגים של מקומות ושדות של נתוני מקומות. גישה למבחר מורחב של סוגי מקומות ושדות של נתוני מקומות.

השוואת קוד (ווידג'טים)

בקטע הזה מוצגת השוואה בין הקוד של ההשלמה האוטומטית כדי להמחיש את ההבדלים בין הווידג'ט הקודם של השלמה אוטומטית של מקומות לבין הרכיב החדש של השלמה אוטומטית של מקומות.

ווידג'ט של השלמה אוטומטית למקומות (קודם)

שירות Places מציע שני סוגים של ווידג'טים של מילוי אוטומטי. אפשר להוסיף אותם באמצעות הכיתות Autocomplete ו-SearchBox. אפשר להוסיף כל סוג של ווידג'ט למפה כפקד מפה, או להטמיע אותו ישירות בדף אינטרנט. בדוגמת הקוד הבאה מוצגת הטמעה של ווידג'ט Autocomplete בתור רכיב בקרה של מפה.

  • ה-constructor של הווידג'ט Autocomplete מקבל שני ארגומנטים:
    • אלמנט HTML מסוג input מסוג text. זהו שדה הקלט ששירות ההשלמה האוטומטית יעקוב אחריו ויצרף אליו את התוצאות שלו.
    • ארגומנטים אופציונליים של AutocompleteOptions, שבהם אפשר לציין אפשרויות נוספות כדי להגביל את השאילתה.
  • כדי להגדיר גבולות, אפשר לקרוא ל-autocomplete.bindTo() כדי לשייך את המופע Autocomplete למפה באופן מפורש.
  • מציינים את השדות של נתוני המקומות באפשרויות להשלמה אוטומטית.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 40.749933, lng: -73.98633 },
    zoom: 13,
    mapTypeControl: false,
  });
  const card = document.getElementById("pac-card");
  const input = document.getElementById("pac-input");
  const options = {
    fields: ["formatted_address", "geometry", "name"],
    strictBounds: false,
  };

  map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);

  const autocomplete = new google.maps.places.Autocomplete(input, options);

  // Bind the map's bounds (viewport) property to the autocomplete object,
  // so that the autocomplete requests use the current map bounds for the
  // bounds option in the request.
  autocomplete.bindTo("bounds", map);

  const infowindow = new google.maps.InfoWindow();
  const infowindowContent = document.getElementById("infowindow-content");

  infowindow.setContent(infowindowContent);

  const marker = new google.maps.Marker({
    map,
    anchorPoint: new google.maps.Point(0, -29),
  });

  autocomplete.addListener("place_changed", () => {
    infowindow.close();
    marker.setVisible(false);

    const place = autocomplete.getPlace();

    if (!place.geometry || !place.geometry.location) {
      // User entered the name of a Place that was not suggested and
      // pressed the Enter key, or the Place Details request failed.
      window.alert("No details available for input: '" + place.name + "'");
      return;
    }

    // If the place has a geometry, then present it on a map.
    if (place.geometry.viewport) {
      map.fitBounds(place.geometry.viewport);
    } else {
      map.setCenter(place.geometry.location);
      map.setZoom(17);
    }

    marker.setPosition(place.geometry.location);
    marker.setVisible(true);
    infowindowContent.children["place-name"].textContent = place.name;
    infowindowContent.children["place-address"].textContent =
      place.formatted_address;
    infowindow.open(map, marker);
  });
}

ווידג'ט של השלמה אוטומטית למקומות (חדש)

בכיתה Place יש את המשנה PlaceAutocompleteElement, שהיא נגזרת של HTMLElement ומספקת רכיב ממשק משתמש שאפשר להוסיף למפה כפקד מפה, או להטמיע ישירות בדף אינטרנט. בדוגמת הקוד הבאה מוסבר איך להטמיע ווידג'ט PlaceAutocompleteElement בתור אמצעי בקרה למפה.

השיפורים בווידג'ט של השלמה אוטומטית של מקומות:

  • ממשק המשתמש של הווידג'ט של ההשלמה האוטומטית תומך בתכנים מותאמים לאזור (כולל שפות RTL) עבור placeholder של קלט הטקסט, הלוגו של רשימת התחזיות והתחזיות למקומות.
  • נגישות משופרת, כולל תמיכה בקוראי מסך ואינטראקציה עם המקלדת.
  • הווידג'ט של ההשלמה האוטומטית מחזיר את הכיתה החדשה Place כדי לפשט את הטיפול באובייקט המוחזר.
  • תמיכה טובה יותר במכשירים ניידים ובמסכים קטנים.
  • ביצועים טובים יותר ומראה גרפי משופר.

ההבדלים העיקריים בהטמעה כוללים:

  • תחזיות לשאילתות לא זמינות בכיתה Autocomplete.
  • השדה PlaceAutocompleteElement נוצר באמצעות PlaceAutocompleteElementOptions.
  • שדות הנתונים של המיקום מצוינים בזמן הבחירה (כשמתבצעת הקריאה ל-fetchFields()).
  • מגדירים את הגבולות באמצעות האפשרות locationBounds או locationRestriction.
  • משייכים את PlaceAutocompleteElement לאלמנט קלט טקסט ב-HTML באמצעות המאפיין id (שעבר בירושה מ-HTMLElement).
let map;
let marker;
let infoWindow;

async function initMap() {
  // Request needed libraries.
  const [{ Map }, { AdvancedMarkerElement }] = await Promise.all([
    google.maps.importLibrary("marker"),
    google.maps.importLibrary("places"),
  ]);

  // Initialize the map.
  map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 40.749933, lng: -73.98633 },
    zoom: 13,
    mapId: "4504f8b37365c3d0",
    mapTypeControl: false,
  });

  const placeAutocomplete =
    new google.maps.places.PlaceAutocompleteElement({
      locationRestriction: map.getBounds(),
    });

  placeAutocomplete.id = "place-autocomplete-input";
  const card = document.getElementById("place-autocomplete-card");

  card.appendChild(placeAutocomplete);
  map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);

  // Create the marker and infowindow.
  marker = new google.maps.marker.AdvancedMarkerElement({
    map,
  });
  infoWindow = new google.maps.InfoWindow({});

  // Add the gmp-placeselect listener, and display the results on the map.
  placeAutocomplete.addEventListener("gmp-placeselect", async ({ place }) => {
    await place.fetchFields({
      fields: ["displayName", "formattedAddress", "location"],
    });
    // If the place has a geometry, then present it on a map.
    if (place.viewport) {
      map.fitBounds(place.viewport);
    } else {
      map.setCenter(place.location);
      map.setZoom(17);
    }

    let content =
      '<div id="infowindow-content">' +
      '<span id="place-displayname" class="title">' +
      place.displayName +
      '</span><br />' +
      '<span id="place-address">' +
      place.formattedAddress +
      '</span>' +
      '</div>';

    updateInfoWindow(content, place.location);
    marker.position = place.location;
  });
}

// Helper function to create an info window.
function updateInfoWindow(content, center) {
  infoWindow.setContent(content);
  infoWindow.setPosition(center);
  infoWindow.open({
    map,
    anchor: marker,
    shouldFocus: false,
  });
}