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

完了

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

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

この演習では、Blazor コンポーネントからの JS 相互運用を使用してクライアント側で JavaScript を呼び出すことで、宅配ピザの会社の既存のアプリを拡張します。 取り消しのポップアップを改善するためにサードパーティの JavaScript ライブラリと統合し、JavaScript から Blazor メソッドを呼び出して顧客による注文のリアルタイムの状態を取得します。

既存のアプリを複製する

Blazor を使用するには、.NET 8.0 SDK がインストールされていることを確認してください。 詳細については、「すべてが正しくインストールされていることを確認する」を参照してください。

  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 のエクスプローラーで、[Pages] を展開し、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 の確認ダイアログが表示されます。

    Screenshot of the default JavaScript confirm dialog.

  8. [OK] を選択し、ピザが注文から削除されていることを確認してください。 別のピザの横にある [X] を選択し、確認ダイアログで [キャンセル] を選択し、ピザが注文のままであることを確認してください。

  9. Shift+F5 キーを押すか、[実行]>[デバッグの停止] の順に選択して、アプリを停止してください。

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

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

  1. Visual Studio Code のエクスプローラーで、[Pages] を展開し、_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. 新しいライブラリを使用するには、Index.razor ファイルの 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 つのボタンが表示されていることを確認し、それらが期待どおりに機能することを確認してください。

    Screenshot showing the SweetAlert dialog box.

  6. Shift+F5 キーを押すか、[実行]>[デバッグの停止] の順に選択して、アプリを停止してください。

注文状態をリアルタイムに表示するように注文ページを更新する

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

  1. Visual Studio Code のエクスプローラーで、[Pages] を展開し、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. アプリでピザを注文してください。 [My Orders] 画面に移動し、注文が不完全な間にアニメーション化された赤いドットが表示され、状態が [配達済み] と表示されると消えるかどうかを確認してください。

    Animation showing the order status changing in real-time.

  9. Shift+F5 キーを押すか、[実行]>[デバッグの停止] の順に選択して、アプリを停止してください。