練習 - 在 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. List<PizzaSpecial> 變數下的 @code 區塊中新增此程式碼:

        Pizza configuringPizza;
        bool showingConfigureDialog;
    
  3. OnInitializedAsync() 方法下新增此程式碼以建立披薩:

        void ShowConfigurePizzaDialog(PizzaSpecial special)
        {
            configuringPizza = new Pizza()
            {
                Special = special,
                SpecialId = special.Id,
                Size = Pizza.DefaultSize
            };
    
            showingConfigureDialog = true;
        }
    
  4. 藉由允許客戶選取披薩的 ShowConfigurePizzaDialog 標記來讓網頁呼叫伺服器端 <li> 方法。 將該 <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. @code 區塊中移除 configuringPizzashowingConfigureDialogShowConfigurePizzaDialog()。 目前看起來應該如下所示:

    @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 區塊中新增兩個新的參數:

      @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 或選取 [執行]。 然後選取 [開始偵錯]。

應用程式現在應該會讓客戶將已設定的披薩取消或新增到訂單。 我們無法在披薩尺寸變更時顯示目前的訂單或更新價格。 我們將在下一個練習中新增這些功能。