AMP

使用遠端資料

如果您的可繫結資料過於龐大或複雜,以致於無法在頁面載入時擷取,該怎麼辦?或者,如果每個 SKU 的價格都需要很長時間才能查詢,又該怎麼辦?查詢未瀏覽商品的 SKU 價格是徒勞無功的。

<amp-state> 支援透過其 src 屬性擷取遠端資料,該屬性會從 CORS 端點擷取 JSON。此擷取會在頁面載入時執行一次,且適用於確保資料的新鮮度 (尤其是在從快取提供服務時)。

您也可以繫結 <amp-state> 元素的 src 屬性。這表示使用者動作可以觸發將遠端 JSON 資料擷取到頁面的可繫結狀態。

擷取襯衫的可用尺寸

讓我們利用擷取遠端資料的功能,查詢範例中 SKU 的價格。我們的 Express.js 開發伺服器在 app.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 時擷取此襯衫資料。將 [src] 繫結新增至我們的 amp-state#shirts 元素

<!-- 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>

注意 – amp-bind 不會在頁面載入時執行,而僅會回應明確的使用者動作。這可確保初始頁面載入在各個頁面之間都能保持一致的快速,而與 amp-bind 的使用方式無關。

不同襯衫價格

現在我們已正確顯示可用尺寸,接下來請確保也顯示正確的價格。

我們的 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]">

試用看看:如果您選取無庫存的尺寸,您就無法將其加入購物車。