Di chuyển sang tính năng Tự động hoàn tất địa điểm mới

Tự động hoàn thành địa điểm là một tính năng của thư viện Địa điểm trong Maps JavaScript API. Bạn có thể sử dụng tính năng tự động hoàn thành để cung cấp cho ứng dụng của mình hành vi tìm kiếm nhập trước của trường tìm kiếm trên Google Maps.

Trang này giải thích sự khác biệt giữa tính năng Tự động hoàn thành địa điểm cũ và mới. Trong cả hai phiên bản, có hai cách chung để tích hợp tính năng Tự động hoàn thành:

Giao diện lập trình tự động hoàn thành

Bảng sau đây liệt kê một số điểm khác biệt chính trong việc sử dụng tính năng Tự động hoàn thành địa điểm có lập trình giữa Dịch vụ tự động hoàn thành địa điểm (cũ)Autocomplete Data API (mới):

PlacesService (Cũ) Place (Mới)
Tài liệu tham khảo về Dịch vụ tự động hoàn thành của Places Tài liệu tham khảo về Dữ liệu tự động hoàn thành (mới)
AutocompletionRequest AutocompleteRequest
AutocompleteService.getPlacePredictions AutocompleteSuggestion.fetchAutocompleteSuggestions
AutocompletePrediction PlacePrediction
Các phương thức yêu cầu sử dụng lệnh gọi lại để xử lý đối tượng kết quả và phản hồi PlacesServiceStatus. Sử dụng Lời hứa và hoạt động không đồng bộ.
Các phương thức yêu cầu kiểm tra PlacesServiceStatus. Không cần kiểm tra trạng thái, có thể sử dụng tính năng xử lý lỗi chuẩn.
Các trường dữ liệu vị trí được đặt làm tuỳ chọn khi tạo thực thể Autocomplete. Các trường dữ liệu vị trí được đặt sau khi fetchFields() được gọi.
Hỗ trợ tính năng dự đoán cụm từ tìm kiếm (chỉ SearchBox). Không có nội dung dự đoán truy vấn trong lớp Autocomplete.
Chỉ giới hạn ở một nhóm cố định các loại địa điểmtrường dữ liệu địa điểm. Truy cập vào nhiều lựa chọn hơn về loại địa điểmtrường dữ liệu địa điểm.

Cả API Tự động hoàn thành cũ và mới đều sử dụng những thông tin sau:

So sánh mã (có lập trình)

Phần này so sánh mã cho tính năng tự động hoàn thành để minh hoạ sự khác biệt giữa dịch vụ Địa điểm và lớp Địa điểm, đối với các giao diện có lập trình.

Truy xuất cụm từ gợi ý của tính năng tự động hoàn thành (cũ)

Dịch vụ Địa điểm cũ cho phép bạn truy xuất các dự đoán tự động hoàn thành theo phương thức lập trình để có nhiều quyền kiểm soát hơn đối với giao diện người dùng so với lớp Autocomplete. Trong ví dụ sau, một yêu cầu duy nhất được thực hiện cho "par", với AutocompletionRequest bao gồm giá trị đầu vào và một tập hợp các giới hạn để tạo độ lệch cho dự đoán. Ví dụ này trả về danh sách các thực thể AutocompletePrediction và hiển thị nội dung mô tả cho từng thực thể. Hàm ví dụ cũng tạo một mã thông báo phiên và áp dụng mã thông báo đó cho yêu cầu.

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);
}

Truy xuất cụm từ gợi ý của tính năng tự động hoàn thành (mới)

Lớp Địa điểm mới cũng cho phép bạn truy xuất các dự đoán tự động hoàn thành theo phương thức lập trình để có nhiều quyền kiểm soát hơn đối với giao diện người dùng so với lớp PlaceAutocompleteElement. Trong ví dụ sau, một yêu cầu duy nhất được thực hiện cho "par", với AutocompleteRequest bao gồm giá trị đầu vào và một tập hợp các giới hạn để tạo độ lệch cho dự đoán. Ví dụ này trả về danh sách các thực thể placePrediction và hiển thị nội dung mô tả cho từng thực thể. Hàm ví dụ cũng tạo một mã thông báo phiên và áp dụng mã thông báo đó cho yêu cầu.

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}`
}

Đặt tiện ích tự động hoàn thành

Bảng sau đây liệt kê một số điểm khác biệt chính trong việc sử dụng tiện ích tự động điền giữa dịch vụ Địa điểm (cũ) và lớp Địa điểm (mới):

Dịch vụ Địa điểm (Cũ) Địa điểm (Mới)
Lớp Autocomplete để dự đoán địa điểm. Lớp PlaceAutocompleteElement để dự đoán địa điểm.
Lớp SearchBox
để dự đoán truy vấn.
Không có nội dung dự đoán truy vấn trong lớp Autocomplete.
Chỉ có văn bản giữ chỗ đầu vào mặc định mới được bản địa hoá. Phần giữ chỗ nhập văn bản, biểu trưng danh sách nội dung gợi ý và nội dung gợi ý địa điểm đều hỗ trợ bản địa hoá theo khu vực.
Tiện ích sử dụng setBounds() hoặc autocomplete.bindTo() để ràng buộc (thiên vị) nội dung tìm kiếm trong các giới hạn đã chỉ định và strictBounds để hạn chế kết quả trong các giới hạn đã chỉ định. Tiện ích sử dụng thuộc tính locationBias để thiên lệch kết quả theo các giới hạn đã chỉ định và thuộc tính locationRestriction để giới hạn phạm vi tìm kiếm theo các giới hạn đã chỉ định.
Bạn chỉ có thể tích hợp tiện ích bằng cách sử dụng phần tử đầu vào HTML tiêu chuẩn. Bạn có thể tích hợp tiện ích bằng cách sử dụng phần tử đầu vào HTML tiêu chuẩn hoặc phần tử gmp-place-autocomplete.
Khi sử dụng tiện ích, người dùng có thể yêu cầu những nội dung không hợp lệ (ví dụ: "bisneyland"); trường hợp này phải được xử lý rõ ràng. Tiện ích này sẽ chỉ trả về kết quả cho các đề xuất được cung cấp và không thể đưa ra yêu cầu cho các giá trị tuỳ ý; do đó, bạn không cần xử lý các yêu cầu có thể không hợp lệ.
Trả về thực thể PlaceResult cũ. Trả về thực thể Place.
Các trường dữ liệu vị trí được đặt làm tuỳ chọn cho đối tượng Autocomplete. Các trường dữ liệu vị trí được đặt khi người dùng thực hiện lựa chọn và fetchFields() được gọi.
Chỉ giới hạn ở một nhóm cố định các loại địa điểmtrường dữ liệu địa điểm. Truy cập vào nhiều lựa chọn hơn về loại địa điểmtrường dữ liệu địa điểm.

So sánh mã (tiện ích)

Phần này so sánh mã cho tính năng tự động hoàn thành để minh hoạ sự khác biệt giữa Tiện ích tự động hoàn thành địa điểm cũ và phần tử Tự động hoàn thành địa điểm mới.

Tiện ích Tự động hoàn thành của Place (cũ)

Dịch vụ Địa điểm cung cấp hai loại tiện ích tự động điền mà bạn có thể thêm bằng cách sử dụng các lớp AutocompleteSearchBox. Bạn có thể thêm từng loại tiện ích vào bản đồ dưới dạng thành phần điều khiển bản đồ hoặc nhúng trực tiếp vào trang web. Ví dụ về mã sau đây cho thấy cách nhúng tiện ích Autocomplete dưới dạng thành phần điều khiển bản đồ.

  • Hàm khởi tạo tiện ích Autocomplete nhận hai đối số:
    • Phần tử input HTML thuộc loại text. Đây là trường nhập mà dịch vụ tự động hoàn thành sẽ theo dõi và đính kèm kết quả của dịch vụ.
    • Đối số AutocompleteOptions không bắt buộc, trong đó bạn có thể chỉ định thêm các tuỳ chọn để ràng buộc truy vấn.
  • Để đặt giới hạn, bạn có thể liên kết thực thể Autocomplete với bản đồ một cách rõ ràng bằng cách gọi autocomplete.bindTo().
  • Chỉ định các trường dữ liệu vị trí trong các tuỳ chọn để tự động hoàn thành.
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);
  });
}

Tiện ích Tự động hoàn thành của Place (Mới)

Lớp Địa điểm cung cấp PlaceAutocompleteElement, một lớp con HTMLElement cung cấp thành phần giao diện người dùng có thể được thêm vào bản đồ dưới dạng thành phần điều khiển bản đồ hoặc nhúng trực tiếp vào trang web. Ví dụ về mã sau đây cho thấy cách nhúng tiện ích PlaceAutocompleteElement dưới dạng thành phần điều khiển bản đồ.

Tiện ích Tự động điền địa điểm đã được cải thiện theo những cách sau:

  • Giao diện người dùng tiện ích Tự động hoàn thành hỗ trợ bản địa hoá theo khu vực (bao gồm cả các ngôn ngữ RTL) cho phần giữ chỗ nhập văn bản, biểu trưng danh sách nội dung gợi ý và nội dung gợi ý về địa điểm.
  • Cải thiện khả năng hỗ trợ tiếp cận, bao gồm cả tính năng hỗ trợ trình đọc màn hình và tương tác bằng bàn phím.
  • Tiện ích Tự động hoàn thành trả về lớp Place mới để đơn giản hoá việc xử lý đối tượng được trả về.
  • Hỗ trợ tốt hơn cho thiết bị di động và màn hình nhỏ.
  • Hiệu suất tốt hơn và giao diện đồ hoạ được cải thiện.

Sau đây là một số điểm khác biệt chính về cách triển khai:

  • Không có nội dung dự đoán truy vấn trong lớp Autocomplete.
  • PlaceAutocompleteElement được tạo bằng PlaceAutocompleteElementOptions.
  • Các trường dữ liệu vị trí được chỉ định tại thời điểm lựa chọn (khi fetchFields() được gọi).
  • Đặt giới hạn bằng cách sử dụng tuỳ chọn locationBounds hoặc locationRestriction.
  • Liên kết PlaceAutocompleteElement với phần tử nhập văn bản HTML bằng cách sử dụng thuộc tính id (kế thừa từ 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,
  });
}