演習 - Blazor アプリケーションでデータを共有する

完了

これで、アプリがデータベースに接続されたので、顧客のピザを注文してアレンジする機能を追加します。

Blazing Pizza ではあなたに、お客様がスペシャル ピザのサイズを変更できる機能を構築してほしいと考えています。 注文を保存する必要があるので、コンテナー サービスにアプリケーションの状態を保存することにしました。

この演習では、新しい注文構成コンポーネントにデータを渡し、OrderState スコープ付きサービスにアプリの状態を保存する方法を確認します。

新しい注文構成ダイアログを追加する

  1. アプリがまだ実行中の場合は、停止します。

  2. Visual Studio Code で、[共有] フォルダーを右クリックし、[新しいファイル] を選びます。

  3. ファイル名として「ConfigurePizzaDialog.razor」と入力します。

  4. 新しい注文コンポーネントの UI に、このコードを入力します。

    @inject HttpClient HttpClient
    
    <div class="dialog-container">
        <div class="dialog">
            <div class="dialog-title">
                <h2>@Pizza.Special.Name</h2>
                @Pizza.Special.Description
            </div>
            <form class="dialog-body">
                <div>
                    <label>Size:</label>
                    <input type="range" min="@Pizza.MinimumSize" max="@Pizza.MaximumSize" step="1" />
                    <span class="size-label">
                        @(Pizza.Size)" (£@(Pizza.GetFormattedTotalPrice()))
                    </span>
                </div>
            </form>
    
            <div class="dialog-buttons">
                <button class="btn btn-secondary mr-auto" >Cancel</button>
                <span class="mr-center">
                    Price: <span class="price">@(Pizza.GetFormattedTotalPrice())</span>
                </span>
                <button class="btn btn-success ml-auto" >Order ></button>
            </div>
        </div>
    </div>
    

    このコンポーネントは、選択されたおすすめピザを表示し、お客様がピザのサイズを選択できるようにするダイアログです。

    このコンポーネントには、ピザのメンバー値にアクセスするために、インデックス ページ コンポーネントからのおすすめピザが必要です。

  5. Blazor の @code ブロックを追加して、パラメーターをコンポーネントに渡せるようにします。

    @code {
        [Parameter] public Pizza Pizza { get; set; }
    }
    

ピザを注文する

お客様がピザを選択すると、ダイアログでピザのサイズを変更できるようにする必要があります。 この対話機能を追加するために、index.razor コントロールを拡張しましょう。

  1. エクスプローラーで [ページ] を展開し、Index.razor を選びます。

  2. @code ブロック内の List<PizzaSpecial> 変数の下に、次のコードを追加します。

        Pizza configuringPizza;
        bool showingConfigureDialog;
    
  3. OnInitializedAsync() メソッドの下にピザを作成する次のコードを追加します。

        void ShowConfigurePizzaDialog(PizzaSpecial special)
        {
            configuringPizza = new Pizza()
            {
                Special = special,
                SpecialId = special.Id,
                Size = Pizza.DefaultSize
            };
    
            showingConfigureDialog = true;
        }
    
  4. お客様がピザの <li> タグを選択できるようにすることで、Web ページでサーバー側の ShowConfigurePizzaDialog メソッドを呼び出せるようにします。 <li> 行を次のコードに置き換えます。

    <li @onclick="@(() => ShowConfigurePizzaDialog(special))" style="background-image: url('@special.ImageUrl')">
    

    お客様がピザを選択すると、サーバーでおすすめピザ データでピザを作成する ShowConfigurePizzaDialog メソッドが実行され、showingConfigureDialog 変数が true に設定されます。

  5. このページには、新しい ConfigurePizzaDialog コンポーネントを表示する方法が必要です。 @code ブロックの上に次のコードを追加します。

    @if (showingConfigureDialog)
    {
        <ConfigurePizzaDialog Pizza="configuringPizza" />
    }
    

    index.razor ファイルの全体は次の例のようになっているはずです。

        @page "/"
        @inject HttpClient HttpClient
        @inject NavigationManager NavigationManager
    
        <div class="main">
          <h1>Blazing Pizzas</h1>
          <ul class="pizza-cards">
            @if (specials != null)
            {
              @foreach (var special in specials)
              {
                <li @onclick="@(() => ShowConfigurePizzaDialog(special))" style="background-image: url('@special.ImageUrl')">
                  <div class="pizza-info">
                  <span class="title">@special.Name</span>
                  @special.Description
                  <span class="price">@special.GetFormattedBasePrice()</span>
                  </div>
                </li>
              }
            }
          </ul>
        </div>
    
        @if (showingConfigureDialog)
        {
            <ConfigurePizzaDialog Pizza="configuringPizza" />
        }
    
        @code {
          List<PizzaSpecial> specials = new();
          Pizza configuringPizza;
          bool showingConfigureDialog;
    
          protected override async Task OnInitializedAsync()
          {
              specials = await HttpClient.GetFromJsonAsync<List<PizzaSpecial>>(NavigationManager.BaseUri + "specials");
          }
    
          void ShowConfigurePizzaDialog(PizzaSpecial special)
          {
              configuringPizza = new Pizza()
              {
                  Special = special,
                  SpecialId = special.Id,
                  Size = Pizza.DefaultSize
              };
    
              showingConfigureDialog = true;
          }
        }
    
  6. F5 キーを押すか、[実行] を選びます。 [デバッグの開始] を選びます。

  7. ピザを選択し、新しいダイアログが表示されることを確認します。

    ピザの注文ダイアログを示すスクリーンショット。

注文の状態を処理する

現時点では、アプリで構成ダイアログが表示されますが、キャンセルや、ピザの注文への移動はできません。 注文の状態を管理するには、新しい注文状態コンテナー サービスを追加します。

  1. アプリがまだ実行中の場合は、停止します。

  2. BlazingPizza フォルダーに新しいフォルダーを作成します。 それに Services という名前を付けます。

  3. Services フォルダーに新しいファイルを作成します。 それに OrderState.cs という名前を付けます。

  4. クラスにこのコードを入力します。

    namespace BlazingPizza.Services;
    
    public class OrderState
    {
        public bool ShowingConfigureDialog { get; private set; }
        public Pizza ConfiguringPizza { get; private set; }
        public Order Order { get; private set; } = new Order();
    
        public void ShowConfigurePizzaDialog(PizzaSpecial special)
        {
            ConfiguringPizza = new Pizza()
            {
                Special = special,
                SpecialId = special.Id,
                Size = Pizza.DefaultSize,
                Toppings = new List<PizzaTopping>(),
            };
    
            ShowingConfigureDialog = true;
        }
    
        public void CancelConfigurePizzaDialog()
        {
            ConfiguringPizza = null;
    
            ShowingConfigureDialog = false;
        }
    
        public void ConfirmConfigurePizzaDialog()
        {
            Order.Pizzas.Add(ConfiguringPizza);
            ConfiguringPizza = null;
    
            ShowingConfigureDialog = false;
        }
    }
    

    現在、index.razor コンポーネントには、新しいクラスに移動できるコードがあることがわかります。 次の手順は、このサービスをアプリで使用できるようにすることです。

  5. エクスプローラーで、Program.cs を選びます。

  6. ファイルの builder.Services. で始まる行の部分に、次の行を追加します。

    builder.Services.AddScoped<OrderState>();
    

    前の演習から、ここにデータベース コンテキストを追加しました。 このコードでは、新しい OrderState サービスを追加します。 このコードを配置することで、index.razor コンポーネントでそれを使用できるようになります。

  7. 次の using ディレクティブをファイルの先頭に追加して、OrderState クラスを解決します。

    using BlazingPizza.Services;
    
  8. エクスプローラーで [ページ] を展開し、Index.razor を選びます。

  9. ファイルの先頭の @inject NavigationManager NavigationManager の下に、次のコードを追加します。

    @using BlazingPizza.Services
    @inject OrderState OrderState
    
  10. configuringPizzashowingConfigureDialogShowConfigurePizzaDialog()@code ブロックから削除します。 その結果、次のようになります。

    @code {
        List<PizzaSpecial> specials = new List<PizzaSpecial>();
    
        protected override async Task OnInitializedAsync()
        {
            specials = await HttpClient.GetFromJsonAsync<List<PizzaSpecial>>(NavigationManager.BaseUri + "specials");
        }
    }
    

    削除されたものを参照しているすべてのコードでエラーが発生します。

  11. ShowConfigurePizzaDialog(special)) の呼び出しを、OrderState バージョンを使用するように変更します。

    <li @onclick="@(() => OrderState.ShowConfigurePizzaDialog(special))" style="background-image: url('@special.ImageUrl')">
    
  12. 参照をブール値の showingConfigureDialog に変更します。

    @if (OrderState.ShowingConfigureDialog)
    
  13. configuringPizza を使用してパラメーターを変更します。

    <ConfigurePizzaDialog Pizza="OrderState.ConfiguringPizza" />
    
  14. F5 キーを押すか、[実行] を選びます。 [デバッグの開始] を選びます。

    すべてが正しければ、何の違いも見られません。 ダイアログは前と同じように表示されます。

キャンセルとピザの注文をする

OrderState クラスにはまだ使用していない 2 つのメソッドがあることに気づいているかもしれません。 CancelConfigurePizzaDialogConfirmConfigurePizzaDialog メソッドは、お客様が注文を確認した場合に、ダイアログを閉じ、ピザを Order オブジェクトに追加します。 これらのメソッドを構成ダイアログのボタンに接続してみましょう。

  1. アプリがまだ実行中の場合は、停止します。

  2. エクスプローラーで、[共有] を展開します。 次に、ConfigurePizzaDialog.razor を選びます。

  3. @code ブロックに、2 つの新しいパラメーターを追加します。

      @code {
        [Parameter] public Pizza Pizza { get; set; }
        [Parameter] public EventCallback OnCancel { get; set; }
        [Parameter] public EventCallback OnConfirm { get; set; }
      }
    
  4. ボタンに、@onclick ディレクティブを追加できるようになりました。 ダイアログのボタンの現在のコードをこのマークアップに変更します。

      <div class="dialog-buttons">
          <button class="btn btn-secondary mr-auto" @onclick="OnCancel">Cancel</button>
          <span class="mr-center">
              Price: <span class="price">@(Pizza.GetFormattedTotalPrice())</span>
          </span>
          <button class="btn btn-success ml-auto" @onclick="OnConfirm">Order ></button>
      </div>
    
  5. 最後のステップは、注文のキャンセルと確認のために OrderState メソッドを渡すことです。 エクスプローラーで、[ページ] を展開します。 次に、Index.razor を選択します。

  6. ConfigurePizzaDialog コンポーネントの呼び出しのコードを変更します。

        <ConfigurePizzaDialog
          Pizza="OrderState.ConfiguringPizza"
          OnCancel="OrderState.CancelConfigurePizzaDialog"
          OnConfirm="OrderState.ConfirmConfigurePizzaDialog" />
    
  7. F5 キーを押すか、[実行] を選びます。 [デバッグの開始] を選びます。

アプリで、お客様がキャンセルしたり、構成されたピザを注文に追加したりできるようになったはずです。 ピザのサイズが変更されたときに、現在の注文を表示したり、価格を更新したりすることができません。 これらの機能を、次の演習で追加します。