練習 - 在 Blazor 應用程式中使用 JavaScript 程式庫

已完成

在客戶將披薩新增至訂單之後,他們可以選取 X 圖示,在不確認的情況下從訂單中移除披薩。 為了防止客戶不小心從訂單中移除披薩,披薩公司希望您新增一個商品移除的確認對話框。

披薩公司也希望客戶能夠即時查看訂單的進度。 您必須更新訂單詳細數據頁面,以持續查詢訂單狀態,併為客戶提供頁面正在更新的意見反應。

在本練習中,您會使用 Blazor 元件中的 JS Interop 擴充披薩外賣公司現有的應用程式,以便在用戶端上呼叫 JavaScript。 您可以與第三方 JavaScript 連結庫整合,以改善取消快顯,並從 JavaScript 呼叫 Blazor 方法以取得客戶訂單的實時狀態。

複製現有的應用程式

本課程模組使用 .NET 9.0 SDK。 確認您已在慣用的命令終端中執行下列命令來安裝 .NET 9.0:

dotnet --list-sdks

類似下列範例的輸出隨即出現:

8.0.100 [C:\Program Files\dotnet\sdk]
9.0.100 [C:\Program Files\dotnet\sdk]

確定已列出開頭為 9 的版本。 如果未列出或找不到命令, 請安裝最新的 .NET 9.0 SDK

如需詳細資訊,請參閱 使用 Blazor 使用 ASP.NET Core 建置您的第一個 Web 應用程式

  1. 開啟 Visual Studio Code,然後從頂端功能表中選取 [ 終端機>新增終端機 ],以開啟整合式終端機。

  2. 在終端機中,切換至您要建立專案的目錄。

  3. 執行下列命令,將應用程式從 GitHub 複製到本機子目錄。

    git clone https://github.com/MicrosoftDocs/mslearn-build-interactive-components-blazor.git BlazingPizza
    
  4. 在頂端功能表欄中,選取 [ 檔案>開啟資料夾]。

  5. 在 [ 開啟資料夾] 對話框中,流覽至 BlazingPizza 資料夾,然後選取 [ 選取資料夾]。

    如果 Visual Studio Code 提示您遺失資產或未解決的相依性,請選取 [是 ] 或 [ 還原]。

  6. 若要執行應用程式並檢查一切正常運作,請按 F5 或選取 [ 執行>開始偵錯]。

  7. 在 Web 應用程式中,選取一些披薩,並將其新增至您的訂單。 在訂單清單中有幾個披薩後,請選取其中一個披薩旁的 X,並確認項目在沒有任何提示的情況下消失。

  8. Shift+F5 或選取 [ 執行>停止偵錯 ] 以停止應用程式。

重構訂單程式

若要使用 JS Interop,您可以插入 IJSRuntime 抽象概念。

  1. 在 Visual Studio Code Explorer 中,展開 [頁面 ],然後選取 [Index.razor]。

  2. Index.razor 檔案中,於語句 @inject OrderState OrderState 之後,新增如下所示的 IJSRuntime 插入。

    @inject OrderState OrderState
    @inject IJSRuntime JavaScript
    
  3. 目前,移除披薩功能的onclick事件會直接呼叫OrderState.RemoveConfiguredPizza(configuredPizza))方法。 使用下列程式碼來取代整個 <a @onclick="@(() => OrderState.RemoveConfiguredPizza(configuredPizza))" class="delete-item">❌</a> 項目:

    <button type="button" class="close text-danger" aria-label="Close"
         @onclick="@(async () => await RemovePizzaConfirmation(configuredPizza))">
         <span aria-hidden="true">&times;</span>
    </button>
    
  4. @code 檔案結尾的 指示詞中,新增方法來呼叫原生JavaScript confirm 函式。 如果客戶從提示中選取 [確定 ],方法會呼叫 OrderState.RemoveConfiguredPizza 以從訂單中移除披薩。 否則,披薩仍然在訂單中。

    async Task RemovePizzaConfirmation(Pizza removePizza)
    {
        if (await JavaScript.InvokeAsync<bool>(
            "confirm",
            $"""Do you want to remove the "{removePizza.Special!.Name}" from your order?"""))
        {
            OrderState.RemoveConfiguredPizza(removePizza);
        }
    }
    

    伺服器使用 IJSRuntime.InvokeAsync 方法來在用戶端呼叫 confirm 函式。 來自呼叫的回應會傳回bool值。 如果確認對話框的結果為 true,則會從訂單中移除披薩。

  5. 按下 F5 或選取 [執行]>[啟動偵錯]

  6. 在應用程式中,將一些披薩新增至您的訂單。

  7. 當訂單中有一些披薩之後,請選取其中一個披薩旁的 X。 標準 JavaScript 確認對話框隨即出現。

    預設 JavaScript 確認對話框的螢幕快照。

  8. 選取 [確定 ],並確認披薩已從您的訂單中移除。 選取另一個披薩旁的 X,在確認對話方塊中選取 [取消],然後確認披薩仍保留在您的訂單中。

  9. Shift+F5 或選取 [ 執行>停止偵錯 ] 以停止應用程式。

將第三方 JavaScript 連結庫新增至 Blazor 應用程式

披薩公司想要在確認對話框中的按鈕上更清楚的文字,並且想要在對話框中使用其商標和樣式。 經過一些研究之後,您決定使用名為 SweetAlert 的小型 JavaScript 函式庫作為標準對話框的良好替代方案。

  1. 在 Visual Studio Code Explorer 中,展開 [頁面 ],然後選取 [_Host.cshtml]。

  2. _Host.cshtml 檔案的結尾處,於 <script src="_framework/blazor.server.js"></script> 行之後,</body> 行之前,新增下列 script 元素以包含 SweetAlert 程式庫。

    <script src="https://cdn.jsdelivr.net/npm/sweetalert@latest/dist/sweetalert.min.js"></script>
    

    SweetAlert 連結庫現在可供用戶端呼叫。

  3. 若要使用新的連結庫,請更新 RemovePizzaConfirmationIndex.razor 檔案中的 方法,如下所示。

    async Task RemovePizzaConfirmation(Pizza removePizza)
    {
        var messageParams = new
        {
            title = "Remove Pizza?",
            text = $"""Do you want to remove the "{removePizza.Special!.Name}" from your order?""",
            icon = "warning",
            buttons = new
            {
                abort = new { text = "No, leave it in my order", value = false },
                confirm = new { text = "Yes, remove pizza", value = true }
            },
            dangerMode = true
        };
    
        if (await JavaScript.InvokeAsync<bool>("swal", messageParams))
        {
            OrderState.RemoveConfiguredPizza(removePizza);
        }
    }
    

    "swal" 名稱是來自協力廠商 sweetalert.js 參考的 JavaScript 函式識別碼。 程式碼呼叫 swal 函式的樣子會類似 confirm。 大部分的更新都是函式接收參數的方式。 SweetAlert 接受 JSON 物件,其中包含它所需的所有設定。

  4. 在 Visual Studio Code 中,按 F5 或選取 [ 執行>開始偵錯]。

  5. 確認 confirm 對話框現在有兩個按鈕:[否],保留在我的訂單中[是] 移除披薩,並確認它們如預期般運作。

    顯示 [SweetAlert] 對話框的螢幕快照。

  6. Shift+F5 或選取 [ 執行>停止偵錯 ] 以停止應用程式。

在訂單頁面上顯示即時訂單狀態

一旦客戶放置披薩訂單, [我的訂單 ] 頁面就會使用 OrderDetail 元件來顯示訂單的目前狀態。 披薩公司希望客戶能夠即時查看訂單的進度。 您會更新元件,以從 JavaScript 呼叫一個 .NET 方法,該方法會持續取得訂單狀態,直到狀態顯示已送達為止。

  1. 在 Visual Studio Code Explorer 中,展開 [頁面 ],然後選取 [OrderDetail.razor]。

  2. OrderDetail.razor 檔案中,於最後 @inject 一個語句底下,於元件頂端新增下列宣告。

    @implements IDisposable
    

    @implements 宣告可讓您定義 Dispose 方法。

  3. 為頁面新增進度環,讓客戶知道頁面正在更新。 在 <div class="track-order-details"> 中,於 @foreach 語句上方新增下列程式碼:

    @if (IsOrderIncomplete)
    {
        <div class="spinner-grow text-danger float-right" role="status">
            <span class="sr-only">Checking your order status...</span>
        </div>
    }
    
  4. @code 指令中的 OrderId 屬性宣告下,新增下列成員。

    bool IsOrderIncomplete =>
        orderWithStatus is null || orderWithStatus.IsDelivered == false;
    
    PeriodicTimer timer = new(TimeSpan.FromSeconds(3));
    
  5. 使用下列程式碼取代現有的 OnParametersSetAsync 方法:

    protected override async Task OnParametersSetAsync() =>
        await GetLatestOrderStatusUpdatesAsync();
    

    程式代碼現在會呼叫 GetLatestOrderStatusUpdatesAsync 方法來更新訂單狀態。

  6. 在更新 OnParametersSetAsync 的方法之後新增下列方法。

    protected override Task OnAfterRenderAsync(bool firstRender) =>
        firstRender ? StartPollingTimerAsync() : Task.CompletedTask;
    
    async Task GetLatestOrderStatusUpdatesAsync()
    {
        try
        {
            orderWithStatus = await HttpClient.GetFromJsonAsync<OrderWithStatus>(
                $"{NavigationManager.BaseUri}orders/{OrderId}");
        }
        catch (Exception ex)
        {
            invalidOrder = true;
            Console.Error.WriteLine(ex);
        }
    }
    
    async Task StartPollingTimerAsync()
    {
        while (IsOrderIncomplete && await timer.WaitForNextTickAsync())
        {
            await GetLatestOrderStatusUpdatesAsync();
            StateHasChanged();
        }
    }
    
    public void Dispose() => timer.Dispose();
    

    元件 OrderDetail 會在頁面轉譯后開始輪詢,並在傳遞訂單時停止輪詢。 當訂單狀態為未完成時,StartPollingTimerAsync 函式會使用 PeriodicTimer 以非同步方式等候下一個刻度。 訂單送達後,將移除動畫轉盤,頁面將顯示最終訂單狀態。

  7. 在 Visual Studio Code 中,按 F5 或選取 [ 執行>開始偵錯]。

  8. 在應用程式中,訂購披薩。 移至 [我的訂單 ] 畫面,並確認在訂單不完整時出現動畫紅點,並在狀態顯示 [ 已交付] 時消失。

    顯示即時變更順序狀態的動畫。

  9. Shift+F5 或選取 [ 執行>停止偵錯 ] 以停止應用程式。