使用远程数据
如果您的可绑定数据太大或太复杂,无法在页面加载时检索怎么办?或者如果每个 SKU 都有一个需要很长时间才能查找的价格怎么办?查找未查看项目的 SKU 的价格是浪费工作。
<amp-state>
通过其 src
属性支持获取远程数据,该属性从 CORS 端点获取 JSON。此获取操作在页面加载时执行一次,对于确保数据的新鲜度非常有用(尤其是在从缓存提供服务时)。
您还可以绑定 <amp-state>
元素的 src
属性。这意味着用户操作可以触发将远程 JSON 数据获取到页面的可绑定状态。
获取衬衫的可用尺码
让我们利用获取远程数据的功能来查找我们示例中的 SKU 价格。我们 app.js
中的 Express.js 开发服务器已经有一个端点 /shirts/sizesAndPrices?shirt=<sku>
,它在给定衬衫 SKU 的情况下,返回每个尺码的可用尺码和价格。它以一秒的人工延迟发送响应,以模拟网络延迟。
请求 | 响应 |
---|---|
GET /shirts/sizesAndPrices?sku=1001 |
{"1001: {"sizes": {"XS": 8.99, "S" 9.99}}} |
与 <amp-state>
元素中的 JSON 数据类似,从这些获取操作返回的远程数据会合并到元素的 id
属性下并可用。例如,可以通过表达式访问上述示例响应中返回的数据
表达式 | 结果 |
---|---|
shirts['1001'].sizes['XS'] |
8.99 |
绑定数据
现在,让我们将此应用于我们的电子商务示例。首先,让我们在选择新的 SKU 时获取此衬衫数据。向我们的 amp-state#shirts
元素添加一个 [src]
绑定
<!-- When `selected.sku` changes, update the `src` attribute and fetch
JSON at the new URL. Then, merge that data under `id` ("shirts"). -->
<amp-state id="shirts" [src]="'/shirts/sizesAndPrices?sku=' + selected.sku">
指示不可用的尺码
接下来,让我们为给定的 SKU 清楚地标记不可用的尺码。"unavailable"
CSS 类会为元素添加一条对角线 - 我们可以将其添加到 amp-selector
中与不可用尺码对应的元素中
<amp-selector name="size">
<table>
<tr>
<!-- If 'XS' size is available for selected SKU, return empty string.
Otherwise, return 'unavailable'. -->
<td [class]="shirts[selected.sku].sizes['XS'] ? '' : 'unavailable'">
<div option="XS">XS</div>
</td>
<td [class]="shirts[selected.sku].sizes['S'] ? '' : 'unavailable'">
<div option="S">S</div>
</td>
<td [class]="shirts[selected.sku].sizes['M'] ? '' : 'unavailable'">
<div option="M">M</div>
</td>
<td [class]="shirts[selected.sku].sizes['L'] ? '' : 'unavailable'">
<div option="L">L</div>
</td>
<td [class]="shirts[selected.sku].sizes['XL'] ? '' : 'unavailable'">
<div option="XL">XL</div>
</td>
</tr>
</table>
</amp-selector>
现在,重新加载页面并尝试一下。选择新的 SKU(衬衫颜色)会导致不可用的尺码被划掉(经过短暂的延迟)。
指定初始状态
但是,有一个小问题 - 黑色衬衫(默认选择的颜色)呢?我们需要将黑色衬衫的尺码和价格数据添加到 amp-state#shirts
,因为 amp-bind
仅响应显式的用户操作而运行
<amp-state id="shirts" [src]="'/shirts/sizesAndPrices?sku=' + selected.sku">
<script type="application/json">
{
"1001": {
"color": "black",
"image": "./shirts/black.jpg",
"sizes": {
"XS": 8.99,
"S": 9.99
}
},
<!-- ... -->
而且,我们需要更新相关元素的默认状态
<amp-selector name="size">
<table>
<tr>
<!-- If 'XS' size is available for selected SKU, return empty string.
Otherwise, return 'unavailable'. -->
<td [class]="shirts[selected.sku].sizes['XS'] ? '' : 'unavailable'">
<div option="XS">XS</div>
</td>
<td [class]="shirts[selected.sku].sizes['S'] ? '' : 'unavailable'">
<div option="S">S</div>
</td>
<!-- Add the 'unavailable' class to the next three <td> elements
to be consistent with the available sizes of the default SKU. -->
<td class="unavailable"
[class]="shirts[selected.sku].sizes['M'] ? '' : 'unavailable'">
<div option="M">M</div>
</td>
<td class="unavailable"
[class]="shirts[selected.sku].sizes['L'] ? '' : 'unavailable'">
<div option="L">L</div>
</td>
<td class="unavailable"
[class]="shirts[selected.sku].sizes['XL'] ? '' : 'unavailable'">
<div option="XL">XL</div>
</td>
</tr>
</table>
</amp-selector>
可变的衬衫价格
既然我们正确显示了可用的尺码,让我们确保也显示正确的价格。
我们的 AMPPAREL 商店的特殊之处在于,衬衫价格同时取决于颜色和尺码。这意味着我们需要一个新变量来跟踪用户选择的尺码。向我们的尺码 amp-selector
元素添加一个新操作
<!-- When an element is selected, set the `selectedSize` variable to the
value of the "option" attribute of the selected element. -->
<amp-selector name="size"
on="select:AMP.setState({selectedSize: event.targetOption})">
请注意,我们没有通过 amp-state#selected
元素初始化 selectedSize
的值。这是因为我们有意不提供默认选择的尺码,而是希望强制用户选择尺码。
AMP.setState()
还可用于定义新变量。表达式会将未定义的变量评估为 null
。添加一个新 <span>
元素,用于包装价格标签,并将默认文本更改为“---”,因为没有默认的尺码选择。
<h6>PRICE :
<!-- Display the price of the selected shirt in the selected size if available.
Otherwise, display the placeholder text '---'. -->
<span [text]="shirts[selected.sku].sizes[selectedSize] || '---'">---</span>
</h6>
现在我们有了正确的价格!尝试一下。
条件启用的按钮
我们快完成了!当所选尺码不可用时,让我们禁用“添加到购物车”按钮
<!-- Disable the "ADD TO CART" button when:
1. There is no selected size, OR
2. The available sizes for the selected SKU haven't been fetched yet
-->
<input type="submit" value="ADD TO CART" disabled
class="mdl-button mdl-button--raised mdl-button--accent"
[disabled]="!selectedSize || !shirts[selected.sku].sizes[selectedSize]">
尝试一下:如果您选择一个不可用的尺码,您将无法将其添加到购物车。