연습 - 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. 웹 페이지에서 서버 쪽 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 폴더에 새 폴더를 만듭니다. 이름을 서비스로 지정합니다.

  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. configuringPizza, showingConfigureDialog, 및 ShowConfigurePizzaDialog()@code 블록에서 제거하십시오. 이제 다음과 같이 표시됩니다.

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

    이제 코드에서 삭제한 요소를 참조할 때마다 오류가 발생합니다.

  11. OrderState 버전을 사용하도록 호출 ShowConfigurePizzaDialog(special)) 을 변경합니다.

    <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 클래스에는 아직 사용되지 않는 두 가지 메서드가 있을 수 있습니다. 및 CancelConfigurePizzaDialog 메서드는 ConfirmConfigurePizzaDialog 대화 상자를 닫고 고객이 주문을 확인하면 피자를 개체에 추가 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 키를 선택하거나 실행을 선택합니다. 그런 다음 , 디버깅 시작을 선택합니다.

이제 앱에서 고객이 구성된 피자를 취소하거나 주문에 추가할 수 있습니다. 피자 크기가 변경될 때 현재 주문을 표시하거나 가격을 업데이트할 방법이 없습니다. 다음 연습에서는 이러한 기능을 추가하겠습니다.