面向现有 Places API 用户采用 Places UI Kit

了解如何将现有的 Places API 或 Place 类实现迁移到 Places UI Kit 组件。

本指南的适用对象

本指南面向已使用 Places API 实现相关功能,并希望更新代码以使用 Places UI Kit 的开发者。 如果您已经具备以下条件,则本课程对您最有帮助:

  • 向 Places API(新版或旧版)端点发出 HTTP 请求。
  • 在 Maps JavaScript API 中使用 Place 类。
  • 处理 API 响应,以便在 Web 应用的界面中呈现地点信息。

前提条件

在 Google Cloud 项目中启用 Places UI Kit。您可以继续使用现有 API 密钥,也可以为 Places UI Kit 生成新密钥。如需了解详情(包括如何限制密钥),请参阅使用 API 密钥。

更新 Maps JavaScript API 加载

Places UI Kit 需要使用动态库导入方法来加载 Maps JavaScript API。如果您使用的是直接脚本加载标记,则必须更新该标记。

更新 Maps JavaScript API 的加载脚本后,导入所需的库以使用 Places UI Kit。

实现地点详情元素

地点详情元素和地点详情紧凑元素是用于呈现地点详情的 HTML 元素。

当前实现

  • 您可以使用 HTTP 请求执行地点详情调用,也可以使用 JavaScript API 地点类。
  • 您解析 API 响应,并使用 HTML 和 CSS 显示地点详情。

迁移到地点详情元素

修改 HTML 结构

确定呈现地点详情的 HTML 容器。将自定义 HTML 元素(名称、地址、照片等的 div、span)替换为地点详情元素 HTML。

有两个元素可供选择:

  • “地点详情”紧凑元素
  • “地点详情”元素

如需详细了解应使用哪种元素,请参阅地点详情元素。

您现有的 HTML 可能如下所示。

<div id="my-place-details-container">
    <h2 id="place-name"></h2>
    <p id="place-address"></p>
    <img id="place-photo" src="" alt="Place photo">
    <!-- ... more custom elements -->
</div>

新 HTML 示例,明确说明要显示哪些内容:

<gmp-place-details-compact orientation="horizontal" truncation-preferred style="display: none;">
    <gmp-place-details-place-request></gmp-place-details-place-request>
    <gmp-place-content-config>
        <gmp-place-media lightbox-preferred></gmp-place-media>
        <gmp-place-address></gmp-place-address>
        <gmp-place-rating></gmp-place-rating>
        <gmp-place-type></gmp-place-type>
        <gmp-place-price></gmp-place-price>
        <gmp-place-accessible-entrance-icon></gmp-place-accessible-entrance-icon>
        <gmp-place-open-now-status></gmp-place-open-now-status>
    </gmp-place-content-config>
</gmp-place-details-compact>

调整 JavaScript 逻辑

现有逻辑

您的现有逻辑可能涉及:

  • 检索地点 ID。
  • 使用 PlacesService().getDetails() 或进行 Web 服务调用。
  • 指定 fields 数组(对于 JS API)或 FieldMask(对于 Web 服务)以请求特定数据。
  • 在回调解析中,手动选择 HTML 元素并使用收到的数据填充这些元素。

以下示例展示了如何实现地点详情:

async function getPlaceDetails(placeId) {
    const { Place } = await google.maps.importLibrary('places');
    // Use place ID to create a new Place instance.
    const place = new Place({
        id: placeId
    });
    await place.fetchFields({
        fields: ['displayName', 'formattedAddress', 'location'],
    });
    // Log the result
    console.log(place.displayName);
    console.log(place.formattedAddress);
}
新逻辑

新逻辑将涉及:

  • 检索您的地点 ID 或地点对象。
  • 获取对 <gmp-place-details-place-request> 元素的引用。
  • 将地点 ID 或地点对象传递给 <gmp-place-details-place-request> 元素上的地点属性。

以下示例展示了如何在 JavaScript 逻辑中实现地点详情界面套件。获取对地点详情元素的引用。如果存在,请获取对“地点详情”地点请求元素的引用,并使用地点 ID 设置地点属性。在上述 HTML 代码示例中,地点详情元素样式设置为 display: none。此设置已更新为 display: block。

function displayPlaceDetailsWithUIKit(placeId) {
  const placeDetailsElement = document.querySelector('gmp-place-details-compact');
  if (placeDetailsElement) {
    const placeDetailsRequest = document.querySelector('gmp-place-details-place-request');
    // Configure the element with the Place ID
    placeDetailsRequest.place = placeId
    placeDetailsElement.style.display = 'block';
    console.log("PlaceDetailsElement configured for place:", placeId);
  } else {
    console.error("PlaceDetailsElement not found in the DOM.");
  }
}

// Example usage:
const placeId = 'ChIJC8HakaIRkFQRiOgkgdHmqkk';
displayPlaceDetailsWithUIKit(placeId);

地点搜索元素是一个 HTML 元素,用于在列表中呈现地点搜索结果。

  • 您可以使用 HTTP 请求执行文本搜索或附近搜索,也可以使用 JavaScript API Place 类。
  • 您可以使用 FieldMask 指定查询参数、位置限制或偏好、类型以及请求的字段。
  • 您需要解析 API 响应,遍历地点数组,并手动创建 HTML 列表项。

修改 HTML 结构

确定用于呈现您的地点列表的 HTML 容器。将自定义 HTML 元素(div、span 等,用于名称、地址等)替换为地点搜索元素 HTML 元素。

您现有的 HTML 可能如下所示:

<div id="search-results-area">
    <h3>Nearby Places:</h3>
    <ul id="manual-places-list">
        <!-- JavaScript would dynamically insert list items here -->
        <!-- Example of what JS might generate:
    <li class="place-entry" data-place-id="SOME_PLACE_ID_1">
      <img class="place-icon" src="icon_url_1.png" alt="Icon">
      <span class="place-name">Place Name One</span> -
      <span class="place-vicinity">123 Main St</span>
    </li>
    <li class="place-entry" data-place-id="SOME_PLACE_ID_2">
      <img class="place-icon" src="icon_url_2.png" alt="Icon">
      <span class="place-name">Place Name Two</span> -
      <span class="place-vicinity">456 Oak Ave</span>
    </li>
    -->
        <li class="loading-message">Loading places...</li>
    </ul>
</div>

地点搜索元素是使用 <gmp-place-search> 组件实现的。如需配置搜索类型,请在其中添加以下某个插槽式配置组件:

  • <gmp-place-text-search-request>,用于文本搜索。
  • <gmp-place-nearby-search-request>(对于附近搜索)。

如需定义结果的显示方式,您可以使用 <gmp-place-all-content> 快捷方式,也可以提供自己的一组单独呈现组件。关键属性(例如 selectable [用于允许点击列表项] 和 orientation [用于水平或垂直布局])可以直接在父级组件上设置。

附近搜索示例
<gmp-place-search orientation="horizontal" selectable>
    <gmp-place-all-content> </gmp-place-all-content>
    <gmp-place-nearby-search-request></gmp-place-nearby-search-request>
</gmp-place-search>
文本搜索示例
<gmp-place-search orientation="horizontal" selectable>
  <gmp-place-all-content> </gmp-place-all-content>
  <gmp-place-text-search-request></gmp-place-text-search-request>
</gmp-place-search>

调整 JavaScript 逻辑

在 JavaScript 中,使用 document.querySelector() 获取对搜索控制器组件的引用。具体取决于您的设置,这将是 <gmp-place-text-search-request> 或 <gmp-place-nearby-search-request> 元素。

接下来,设置此控制器上的属性以定义搜索。所需的属性取决于您要执行的搜索类型。

对于文本搜索 (<gmp-place-text-search-request>),主要属性为 textQuery:

const textSearchController = document.querySelector('gmp-place-text-search-request');
textSearchController.textQuery = 'museums in London';

对于“附近搜索”(<gmp-place-nearby-search-request>),您必须使用 locationRestriction 定义搜索区域。然后,您可以使用 includedTypes 过滤该区域内的特定类型的地点:

const nearbySearchController = document.querySelector('gmp-place-nearby-search-request');
nearbySearchController.locationRestriction = new google.maps.Circle({
    center: { lat: 51.5190, lng: -0.1347 },
    radius: 1000
});
nearbySearchController.includedTypes = ['restaurant'];

父级 <gmp-place-search> 组件会在其控制器的必需属性设置完成后,自动启动新的搜索。

  • 对于文本搜索,系统会在您为 textQuery 赋值时立即运行搜索。
  • 对于附近搜索,系统会在提供有效的 locationRestriction 后运行搜索。

实现基本地点自动补全元素

对于需要不带地点搜索元素提供的界面的搜索体验的开发者,可以使用基本地点自动补全元素。

此元素非常适合创建搜索输入字段,同时让您能够完全控制结果在自定义界面中的显示方式。自动补全元素的唯一职责是在用户输入内容时提供地点预测结果,并以编程方式公开所选地点的地点 ID。

它本身不显示任何详细信息,也不提供任何其他可通过编程方式访问的信息。

当前实现

您的现有逻辑可能涉及:

  • 在页面上呈现一个文本输入字段,该字段会在用户输入内容时调用地点自动补全功能,并显示结果。
  • 使用用户所选地点的地点 ID 来提取更多详细信息,例如使用 Place Details API。
  • 显示所选地点的详细信息。

迁移到地点自动补全元素

修改 HTML 结构

找到并移除您附加了自动补全 widget 的 HTML 元素。它可能使用的是标准 HTML 输入字段。

<input id="pac-input" type="text" placeholder="Search for a location" />

新 HTML 示例,使用 Web 组件方法在网页上初始化基本地点自动补全元素。

<gmp-basic-place-autocomplete></gmp-basic-place-autocomplete>

调整 JavaScript 逻辑

您的 JavaScript 逻辑可能涉及创建附加到 input HTML 元素的自动补全 widget。然后,此 widget 会监听 place_changed 事件,并使用返回的数据触发操作。

要移除的现有 JavaScript 示例:

// Get the input element
const input = document.getElementById("pac-input");

// Create the Autocomplete widget instance
const autocomplete = new google.maps.places.Autocomplete(input, {
  fields: ["place_id", "geometry", "name"]
});

// Add a listener for the 'place_changed' event
autocomplete.addListener("place_changed", () => {
  // Your logic to get and display place information
  console.log(place.place_id);
});

新的 JavaScript 逻辑将获取对基本地点自动补全元素的引用,并监听 gmp-select 事件:

const placeAutocomplete = document.querySelector('gmp-basic-place-autocomplete');

placeAutocomplete.addEventListener('gmp-select', (event) => {
  console.log(event.place);
});

在自动补全下拉菜单中选择地点后,系统会触发 gmp-select 事件。所选地点的地点 ID 可从 event 对象中检索。然后,您可以使用地点 ID 初始化地点详情元素的实例,以显示所选地点的详情。

处理自定义

地点详情元素自定义

方向

地点详情元素可以水平和垂直方向呈现。在 gmp-place-details-compact 上使用 orientation 属性,在垂直和水平之间进行选择。例如:

<gmp-place-details-compact orientation="vertical">

选择要呈现的字段

使用内容元素指定要在地点详情元素中呈现的内容。例如,排除内容元素 <gmp-place-type> 会阻止地点详情元素呈现所选地点的地点类型。如需查看内容元素的完整列表,请参阅 PlaceContentConfigElement 参考文档。

在“地点详情”元素中添加或移除字段不会改变在网页上呈现该元素的费用。

设置 CSS 样式

您可以使用自定义 CSS 属性来配置元素的颜色和字体。 例如,如需将元素背景设置为绿色,请设置以下 CSS 属性:

gmp-place-details-compact {
  --gmp-mat-color-surface: green;
}

如需了解详情,请参阅 PlaceDetailsCompactElement 的参考文档。

地点搜索元素自定义

方向

地点搜索元素可以横向和纵向呈现。使用 <gmp-place-search> 上的 orientation 属性在垂直和水平之间进行选择。例如:

<gmp-place-search orientation="horizontal" selectable>

选择要呈现的字段

使用内容元素指定要在地点搜索元素中呈现的内容。元素 <gmp-place-all-content> 可用于显示所有内容,也可以使用一系列 HTML 标记来配置呈现的内容。

在 <gmp-place-content-config> 中添加 <gmp-place-address> 只会呈现每个地点的地址,例如:

<gmp-place-search orientation="horizontal" selectable>
  <gmp-place-content-config>
    <gmp-place-address></gmp-place-address>
  </gmp-place-content-config>
  <gmp-place-text-search-request></gmp-place-text-search-request>
</gmp-place-search>

基本地点自动补全元素自定义

设置 CSS 样式

您可以使用自定义 CSS 属性来自定义自动补全元素的外观和风格。例如,如需将背景颜色设置为浅紫色,您需要在元素上设置 background-color 属性。

gmp-basic-place-autocomplete {
  background-color: #d993e6;
}

如需了解详情,请参阅 BasicPlaceAutocompleteElement 参考文档。

处理事件和数据

Places UI Kit 元素是交互式组件,可让您以编程方式监听事件和检索数据。

监听事件

您可以向元素添加事件监听器,以便根据用户互动或元素状态触发操作。

选择事件

  • gmp-select:当用户做出选择时,系统会触发此事件。
    • 在地点搜索元素上,当用户点击结果列表中的地点时,会触发此事件。
    • 在基本地点自动补全元素上,当用户点击下拉列表中的联想查询时,会触发此事件。

常见事件

地点搜索、地点详情和基本地点自动补全元素均支持以下事件:

  • gmp-load:在元素及其内容完成加载和渲染时触发。
  • gmp-requesterror:在向服务器发出的请求失败时触发,例如,由于 API 密钥无效。

以编程方式访问元素数据

您可以通过编程方式从元素中检索特定数据,前提是这些元素已加载或已与之互动。

  • 对于地点搜索元素和地点详情元素,您可以检索以下信息:
    • 地点 ID
    • 位置(经纬度)
    • 视口
  • 对于基本地点自动补全元素,您可以检索以下信息:
    • 地点 ID

元素中包含的所有其他数据都无法通过编程方式访问。

如需查看更详细的示例,请参阅地点搜索元素、地点详情元素和基本地点自动补全元素的单独文档。

测试和优化

集成 Places UI Kit 元素后,测试对于确保顺利过渡和良好的用户体验至关重要。您的测试应涵盖几个关键领域,并针对您已实现的所有元素:地点详情、地点搜索和基本地点自动补全元素。

地点详情元素

对于地点详情元素,首先要验证各种地点的详细信息是否正确显示。通过将各种地点 ID 传递给 <gmp-place-details-place-request> 元素的 .place 属性来进行测试。使用代表不同场所类型(具有丰富数据的商家、地图注点、基本地址)以及不同区域或语言的地点的 ID。请密切注意内容的格式、布局和存在情况。

地点搜索元素

如果您已实现地点搜索元素,请验证其在不同搜索场景下的呈现和行为。

  • 对于文本搜索,请通过在 <gmp-place-text-search-request> 元素上设置 textQuery 属性并使用各种输入(宽泛查询、具体地址和具有位置偏向的查询)进行测试。
  • 对于附近搜索,请通过在 <gmp-place-nearby-search-request> 元素上设置 locationRestriction 和 includedTypes 属性进行测试。使用不同的位置大小和类型过滤条件。

确认列表中填充了相关结果,并且在选择后正确触发了 gmp-select 事件。

基本地点自动补全元素

对于基本地点自动补全元素,请重点测试用户互动以及选择事件传递的数据。确认当用户点击联想查询时,gmp-select 事件会可靠地触发。验证事件处理脚本中的 event.place 对象是否包含有效的地点 ID。

最重要的是,测试端到端流程:从自动补全下拉菜单中选择一个地点,并验证其地点 ID 是否可成功用于填充另一个元素,例如地点详情元素。

错误处理

对所有组件进行严格的错误处理测试至关重要。模拟向地点详情元素传递无效或不存在的地点 ID,或为地点搜索元素使用无效的搜索参数。通过模拟网络问题或使用无效的 API 密钥来触发 gmp-requesterror 事件,以确保您的应用能够妥善处理该事件。实现人性化的出错提示和日志记录,以防止界面损坏或令人困惑。