演習 - Blazor アプリで JavaScript ライブラリを使用する

完了

顧客が注文にピザを追加した後、 X アイコンを選択すると、確認なしで注文からピザを削除できます。 顧客が誤って注文からピザを削除するのを防ぐために、ピザ会社は、アイテムの削除の確認プロンプトを追加することを望んでいます。

ピザ会社はまた、顧客が注文がどのように進行しているかをリアルタイムで確認したいと考えています。 注文の詳細ページを更新して注文の状態を継続的に照会し、ページが更新されていることを顧客にフィードバックする必要があります。

この演習では、Blazor コンポーネントからの JS 相互運用機能を使用して、ピザ配送会社の既存のアプリを拡張し、クライアント側で 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 相互運用機能を使用するには、 IJSRuntime 抽象化を挿入します。

  1. Visual Studio Code エクスプローラーで、[ ページ] を展開し、[ 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 関数を呼び出す新しいメソッドを追加します。 顧客がプロンプトから [OK] を 選択した場合、メソッドは注文からピザを削除するために 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. [ OK] を 選択し、ピザが注文から削除されていることを確認します。 別のピザの横にある [X ] を選択し、確認ダイアログで [キャンセル] を選択し、ピザが注文に残っていることを確認します。

  9. Shift+F5 キーを押すか、[実行>ストップ デバッグ] を選択してアプリを停止します。

Blazor アプリにサードパーティの JavaScript ライブラリを追加する

ピザ会社は、確認ダイアログのボタンのテキストをより明確にし、ダイアログ ボックスでブランドとスタイルを使用したいと考えています。 いくつかの調査の後、標準ダイアログの代わりに SweetAlert と呼ばれる小さな JavaScript ライブラリを使用することにしました。

  1. Visual Studio Code エクスプローラーで、[ ページ] を展開し、 _Host.cshtml を選択します。

  2. _Host.cshtml ファイルの末尾で、<script src="_framework/blazor.server.js"></script>行の後、</body>行の前に、SweetAlert ライブラリを含める次のscript要素を追加します。

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

    SweetAlert ライブラリをクライアント側で呼び出すようになりました。

  3. 新しいライブラリを使用するには、RemovePizzaConfirmation ファイル内の メソッドを次のように更新します。

    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ダイアログに「いいえ、注文に残します」と「はい、ピザを削除します」と表示される2つのボタンがあり、それらが期待通りに機能することを確認してください。

    SweetAlert ダイアログ ボックスを示すスクリーンショット。

  6. Shift+F5 キーを押すか、[実行>ストップ デバッグ] を選択してアプリを停止します。

注文ページにリアルタイム注文の状態を表示する

顧客がピザの注文を行うと、[ 個人用注文 ] ページでは、 OrderDetail コンポーネントを使用して注文の現在の状態が表示されます。 ピザ会社は、顧客が注文がどのように進行しているかをリアルタイムで確認することを望んでいます。 コンポーネントを更新して JavaScript から .NET メソッドを呼び出し、状態が配信されるまで注文状態を継続的に取得します。

  1. Visual Studio Code エクスプローラーで、[ ページ] を展開し、[ 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 キーを押すか、[実行>ストップ デバッグ] を選択してアプリを停止します。