ย้ายข้อมูลไปยัง Place Autocomplete เวอร์ชันใหม่

Place Autocomplete เป็นฟีเจอร์ของไลบรารี Places ใน Maps JavaScript API คุณสามารถใช้ฟีเจอร์เติมข้อความอัตโนมัติเพื่อให้แอปพลิเคชันมีลักษณะการค้นหาแบบพิมพ์ล่วงหน้าของช่องค้นหา Google Maps

หน้านี้จะอธิบายความแตกต่างระหว่างฟีเจอร์การเติมข้อความอัตโนมัติของสถานที่แบบเดิมและแบบใหม่ ทั้ง 2 เวอร์ชันมีวิธีทั่วไป 2 วิธีในการผสานรวมการเติมข้อความอัตโนมัติ ดังนี้

อินเทอร์เฟซแบบเป็นโปรแกรมสำหรับการเติมข้อความอัตโนมัติ

ตารางต่อไปนี้แสดงความแตกต่างหลักๆ บางประการในการใช้ Place Autocomplete แบบเป็นโปรแกรมระหว่างบริการ Place Autocomplete (เดิม) กับ Autocomplete Data API (ใหม่)

PlacesService (เดิม) Place (ใหม่)
เอกสารอ้างอิงของ Places Autocomplete Service ข้อมูลอ้างอิงเกี่ยวกับข้อมูลสำหรับการป้อนข้อความอัตโนมัติ (ใหม่)
AutocompletionRequest AutocompleteRequest
AutocompleteService.getPlacePredictions AutocompleteSuggestion.fetchAutocompleteSuggestions
AutocompletePrediction PlacePrediction
เมธอดต้องใช้การเรียกกลับเพื่อจัดการออบเจ็กต์ผลลัพธ์และการตอบกลับPlacesServiceStatus ใช้ Promises และทํางานแบบไม่พร้อมกัน
วิธีการต้องเลือกPlacesServiceStatus ไม่ต้องมีการตรวจสอบสถานะ สามารถใช้การจัดการข้อผิดพลาดมาตรฐานได้
ระบบจะตั้งค่าช่องข้อมูลสถานที่เป็นตัวเลือกเมื่อสร้างอินสแตนซ์ Autocomplete ระบบจะตั้งค่าฟิลด์ข้อมูลสถานที่ในภายหลังเมื่อเรียกใช้ fetchFields()
รองรับการคาดคะเนข้อความค้นหา (SearchBox เท่านั้น) การคาดคะเนข้อความค้นหาไม่พร้อมใช้งานในคลาส Autocomplete
จำกัดไว้ที่ชุดประเภทสถานที่และช่องข้อมูลสถานที่ที่กำหนดไว้ เข้าถึงประเภทสถานที่และช่องข้อมูลสถานที่ที่หลากหลายมากขึ้น

ทั้ง Autocomplete API เดิมและใหม่ใช้ข้อมูลต่อไปนี้

การเปรียบเทียบโค้ด (แบบเป็นโปรแกรม)

ส่วนนี้จะเปรียบเทียบโค้ดสำหรับการเติมข้อความอัตโนมัติเพื่อแสดงความแตกต่างระหว่างบริการ Places กับคลาส Place สำหรับอินเทอร์เฟซแบบเป็นโปรแกรม

เรียกข้อมูลการคาดคะเนการเติมข้อความอัตโนมัติ (เดิม)

บริการ Places รุ่นเดิมช่วยให้คุณเรียกข้อมูลการคาดคะเนการเติมข้อความอัตโนมัติแบบเป็นโปรแกรมได้ เพื่อควบคุมอินเทอร์เฟซผู้ใช้ได้มากกว่าที่คลาส 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);
}

เรียกข้อมูลการคาดคะเนการเติมข้อความอัตโนมัติ (ใหม่)

นอกจากนี้ คลาสสถานที่แบบใหม่ยังช่วยให้คุณเรียกข้อมูลการคาดคะเนการเติมข้อความอัตโนมัติแบบเป็นโปรแกรมเพื่อควบคุมอินเทอร์เฟซผู้ใช้ได้มากกว่าที่คลาส 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 (เดิม) สถานที่ (ใหม่)
คลาส Autocomplete สําหรับการคาดการณ์สถานที่ คลาส PlaceAutocompleteElement สําหรับการคาดการณ์สถานที่
คลาส SearchBox
สําหรับการคาดคะเนคําค้นหา
การคาดคะเนข้อความค้นหาไม่พร้อมใช้งานในคลาส Autocomplete
มีเพียงข้อความตัวยึดตําแหน่งอินพุตเริ่มต้นเท่านั้นที่แปล ตัวยึดตําแหน่งการป้อนข้อความ โลโก้รายการการคาดคะเน และการคาดคะเนสถานที่ล้วนรองรับการแปลเป็นภาษาท้องถิ่นระดับภูมิภาค
วิดเจ็ตใช้ setBounds() หรือ autocomplete.bindTo() เพื่อจำกัด (กำหนดทิศทาง) การค้นหาให้อยู่ภายในขอบเขตที่ระบุ และ strictBounds เพื่อจำกัดผลลัพธ์ให้อยู่ภายในขอบเขตที่ระบุ วิดเจ็ตใช้พร็อพเพอร์ตี้ locationBias เพื่อกำหนดขอบเขตของผลลัพธ์ และพร็อพเพอร์ตี้ locationRestriction เพื่อจำกัดการค้นหาให้อยู่ภายในขอบเขตที่ระบุ
คุณผสานรวมวิดเจ็ตได้โดยใช้องค์ประกอบอินพุต HTML มาตรฐานเท่านั้น วิดเจ็ตผสานรวมได้โดยใช้องค์ประกอบอินพุต HTML มาตรฐานหรือองค์ประกอบ gmp-place-autocomplete
เมื่อใช้วิดเจ็ต ผู้ใช้อาจขอสิ่งที่ไม่ถูกต้อง (เช่น "bisneyland") กรณีนี้ต้องจัดการอย่างชัดแจ้ง วิดเจ็ตจะแสดงเฉพาะผลลัพธ์ของคำแนะนำที่ระบุ และไม่สามารถส่งคำขอค่าที่กำหนดเองได้ จึงไม่จำเป็นต้องจัดการกับคำขอที่อาจไม่ถูกต้อง
แสดงผลอินสแตนซ์ PlaceResult เดิม แสดงผลอินสแตนซ์ Place
ฟิลด์ข้อมูลสถานที่ตั้งได้รับการตั้งค่าเป็นตัวเลือกสําหรับออบเจ็กต์ Autocomplete ระบบจะตั้งค่าช่องข้อมูลสถานที่เมื่อผู้ใช้ทำการเลือกและเรียกใช้ fetchFields()
จำกัดไว้ที่ชุดประเภทสถานที่และช่องข้อมูลสถานที่ที่กำหนดไว้ เข้าถึงประเภทสถานที่และช่องข้อมูลสถานที่ที่หลากหลายมากขึ้น

การเปรียบเทียบโค้ด (วิดเจ็ต)

ส่วนนี้จะเปรียบเทียบโค้ดสำหรับการเติมข้อความอัตโนมัติเพื่อแสดงให้เห็นความแตกต่างระหว่างวิดเจ็ตการเติมข้อความอัตโนมัติของสถานที่เดิมกับองค์ประกอบการเติมข้อความอัตโนมัติของสถานที่ใหม่

วิดเจ็ตการเติมข้อความอัตโนมัติของสถานที่ (เดิม)

บริการ Places มีวิดเจ็ตการเติมข้อความอัตโนมัติ 2 ประเภท ซึ่งคุณเพิ่มได้โดยใช้คลาส Autocomplete และ SearchBox วิดเจ็ตแต่ละประเภทสามารถเพิ่มลงในแผนที่เป็นตัวควบคุมแผนที่ หรือฝังลงในหน้าเว็บได้โดยตรง ตัวอย่างโค้ดต่อไปนี้แสดงการฝังวิดเจ็ต Autocomplete เป็นการควบคุมแผนที่

  • ตัวสร้างวิดเจ็ต Autocomplete ใช้อาร์กิวเมนต์ 2 รายการดังนี้
    • องค์ประกอบ input ของ HTML ประเภท text ช่องนี้คือช่องป้อนข้อมูลที่จะตรวจสอบและแนบผลลัพธ์ของบริการเติมข้อความอัตโนมัติ
    • อาร์กิวเมนต์ AutocompleteOptions ที่ไม่บังคับ ซึ่งคุณสามารถระบุตัวเลือกเพิ่มเติมเพื่อจำกัดการค้นหาได้
  • หากต้องการกําหนดขอบเขต คุณสามารถเชื่อมโยงอินสแตนซ์ Autocomplete กับแผนที่อย่างชัดเจนได้ด้วยการเรียกใช้ autocomplete.bindTo()
  • ระบุช่องข้อมูลสถานที่ในตัวเลือกสำหรับการเติมข้อความอัตโนมัติ
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);
  });
}

วิดเจ็ตการเติมข้อความอัตโนมัติของสถานที่ (ใหม่)

คลาสสถานที่มี PlaceAutocompleteElement ซึ่งเป็นคลาสย่อย HTMLElement ที่ให้คอมโพเนนต์ UI ที่เพิ่มลงในแผนที่เป็นตัวควบคุมแผนที่ หรือฝังลงในหน้าเว็บโดยตรงได้ ตัวอย่างโค้ดต่อไปนี้แสดงการฝังวิดเจ็ต PlaceAutocompleteElement เป็นการควบคุมแผนที่

วิดเจ็ตการเติมข้อความอัตโนมัติของสถานที่ได้รับการปรับปรุงในด้านต่อไปนี้

  • UI ของวิดเจ็ตการเติมข้อความอัตโนมัติรองรับการแปลเป็นภาษาท้องถิ่นระดับภูมิภาค (รวมถึงภาษา RTL) สำหรับตัวยึดตําแหน่งการป้อนข้อความ โลโก้รายการการคาดคะเน และการคาดคะเนสถานที่
  • การช่วยเหลือพิเศษที่ปรับปรุงคุณภาพแล้ว ซึ่งรวมถึงการรองรับโปรแกรมอ่านหน้าจอและการโต้ตอบด้วยแป้นพิมพ์
  • วิดเจ็ตการเติมข้อความอัตโนมัติจะแสดงผลคลาส 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,
  });
}