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]">

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