Exercício – Compartilhar dados em aplicativos Blazor
Agora que seu aplicativo está conectado a um banco de dados, é hora de adicionar a capacidade para os clientes configurarem e pedirem uma pizza.
A Blazing Pizza quer que você construa a capacidade dos clientes de mudar o tamanho de suas pizzas especiais. Você precisa armazenar o pedido e deseja armazenar o estado do aplicativo em um serviço de contêiner.
Neste exercício, você passa dados para um novo componente de configuração de pedido e vê como armazenar o estado do aplicativo em um serviço com o escopo definido como OrderState.
Adicionar uma nova caixa de diálogo de configuração de pedido
Interrompa o aplicativo se ele ainda estiver em execução.
No Visual Studio Code, clique com o botão direito do mouse na pasta Compartilhada e selecione Novo Arquivo.
Insira ConfigurePizzaDialog.razor como o nome do arquivo.
Insira este código para a interface do usuário do novo componente de ordenação:
@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>Esse componente é uma caixa de diálogo que mostra a pizza especial selecionada e permite que o cliente selecione o tamanho da pizza.
O componente precisa de uma pizza especial do componente de página de índice para acessar os valores de membro de uma pizza.
Adicione o bloco Blazor
@codepara permitir que os parâmetros sejam passados para o componente:@code { [Parameter] public Pizza Pizza { get; set; } }
Pedir uma pizza
Quando um cliente seleciona uma pizza, a caixa de diálogo deve permitir que ele altere o tamanho de sua pizza. Vamos aprimorar o controle index.razor para adicionar essa interatividade.
No explorador de arquivos, expanda Páginas e selecione Index.razor.
Adicione este código no
@codebloco sob aList<PizzaSpecial>variável:Pizza configuringPizza; bool showingConfigureDialog;Adicione este código para criar uma pizza sob o
OnInitializedAsync()método:void ShowConfigurePizzaDialog(PizzaSpecial special) { configuringPizza = new Pizza() { Special = special, SpecialId = special.Id, Size = Pizza.DefaultSize }; showingConfigureDialog = true; }Permita que a página da Web chame o método
ShowConfigurePizzaDialogdo lado do servidor, permitindo que os clientes selecionem uma tag<li>de pizza. Substitua a<li>linha por este código:<li @onclick="@(() => ShowConfigurePizzaDialog(special))" style="background-image: url('@special.ImageUrl')">Quando um cliente seleciona uma pizza, o servidor executa o
ShowConfigurePizzaDialogmétodo que cria uma pizza com os dados especiais de pizza e define ashowingConfigureDialogvariável comotrue.A página precisa de uma maneira de exibir o novo
ConfigurePizzaDialogcomponente. Adicione este código acima do@codebloco:@if (showingConfigureDialog) { <ConfigurePizzaDialog Pizza="configuringPizza" /> }O arquivo inteiro
index.razoragora deve ser semelhante a este exemplo:@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; } }Selecione F5 ou selecione Executar. Em seguida, selecione Iniciar Depuração.
Selecione uma pizza e veja a nova caixa de diálogo aparecer.
Gerenciar o estado de um pedido
No momento, o aplicativo mostra a caixa de diálogo de configuração, mas não permite que você cancele ou passe a pedir a pizza. Para gerenciar o estado do pedido, adicione um novo serviço de contêiner de estado do pedido.
Interrompa o aplicativo se ele ainda estiver em execução.
Crie uma nova pasta na pasta BlazingPizza . Nomeie-o Serviços.
Crie um novo arquivo na pasta Serviços . Nomeie-o OrderState.cs.
Insira este código para a classe:
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; } }Observe que há código atualmente no componente index.razor que podemos mover para a nova classe. A próxima etapa é disponibilizar esse serviço no aplicativo.
No explorador de arquivos, selecione Program.cs.
Na parte do arquivo com as linhas que começam com
builder.Services., adicione esta linha:builder.Services.AddScoped<OrderState>();Do exercício anterior, adicionamos nosso contexto de banco de dados aqui. Esse código adiciona o novo
OrderStateserviço. Com esse código em vigor, agora podemos usá-lo noindex.razorcomponente.Adicione a seguinte diretiva
usingno início do arquivo. Essa diretiva resolve todas as referências àOrderStateclasse:using BlazingPizza.Services;No explorador de arquivos, expanda Páginas e selecione Index.razor.
Na parte superior do arquivo, em
@inject NavigationManager NavigationManager, adicione este código:@using BlazingPizza.Services @inject OrderState OrderStateRemova
configuringPizza,showingConfigureDialog, eShowConfigurePizzaDialog()do bloco@code. Ele deve estar assim:@code { List<PizzaSpecial> specials = new List<PizzaSpecial>(); protected override async Task OnInitializedAsync() { specials = await HttpClient.GetFromJsonAsync<List<PizzaSpecial>>(NavigationManager.BaseUri + "specials"); } }Agora há erros em que o código faz referência aos elementos que você excluiu.
Altere a chamada para
ShowConfigurePizzaDialog(special))para usar a versão OrderState.<li @onclick="@(() => OrderState.ShowConfigurePizzaDialog(special))" style="background-image: url('@special.ImageUrl')">Altere a referência para o booliano
showingConfigureDialog:@if (OrderState.ShowingConfigureDialog)Altere o parâmetro usando
configuringPizza:<ConfigurePizzaDialog Pizza="OrderState.ConfiguringPizza" />Selecione F5 ou selecione Executar. Em seguida, selecione Iniciar Depuração.
Se tudo estiver correto, você não verá nenhuma diferença. A caixa de diálogo aparece como antes.
Cancelar e fazer pedidos de pizza
Você pode notar que há dois métodos na classe OrderState que ainda não foram usados. Os métodos CancelConfigurePizzaDialog e ConfirmConfigurePizzaDialog fecham a caixa de diálogo e adicionam a pizza a um objeto Order assim que o cliente confirma o pedido. Vamos conectar esses métodos aos botões de diálogo de configuração.
Interrompa o aplicativo se ele ainda estiver em execução.
No explorador de arquivos, expanda Compartilhado. Em seguida, selecione ConfigurePizzaDialog.razor.
@codeNo bloco, adicione dois novos parâmetros:@code { [Parameter] public Pizza Pizza { get; set; } [Parameter] public EventCallback OnCancel { get; set; } [Parameter] public EventCallback OnConfirm { get; set; } } `` `Os botões agora podem ter
@onclickdiretivas adicionadas. Altere o código atual dos botões de diálogo para esta marcação:<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>A última etapa é transmitir os métodos
OrderStatepara cancelar e confirmar pedidos. No explorador de arquivos, expanda Páginas. Depois, selecione Index.razor.Altere o código da chamada ao componente
ConfigurePizzaDialog:<ConfigurePizzaDialog Pizza="OrderState.ConfiguringPizza" OnCancel="OrderState.CancelConfigurePizzaDialog" OnConfirm="OrderState.ConfirmConfigurePizzaDialog" />Selecione F5 ou selecione Executar. Em seguida, selecione Iniciar Depuração.
O aplicativo agora deve permitir que os clientes cancelem ou adicionem uma pizza configurada a um pedido. Não temos como mostrar o pedido atual ou atualizar os preços quando o tamanho da pizza for alterado. Adicionaremos esses recursos no próximo exercício.