Exercício - Partilhar dados em aplicações Blazor
Agora que seu aplicativo está conectado a um banco de dados, é hora de adicionar a capacidade de os clientes configurarem e pedirem uma pizza.
Blazing Pizza quer que você construa a capacidade de os clientes mudarem 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, vais passar dados para um novo componente de configuração de pedido e aprender como armazenar o estado da aplicação num serviço com o escopo de OrderState.
Adicionar uma nova caixa de diálogo de configuração de ordem
Pare 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.
Digite ConfigurePizzaDialog.razor como o nome do arquivo.
Insira este código para a interface do usuário do novo componente de pedido:
@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>Este 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 da 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; } }
Peça 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 ficheiros, expanda Páginas e, em seguida, selecione Index.razor.
Adicione este código no bloco
@codesob a variávelList<PizzaSpecial>:Pizza configuringPizza; bool showingConfigureDialog;Adicione este código para criar uma pizza sob o método
OnInitializedAsync():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, ao permitir que os clientes selecionem a tag<li>de uma pizza. Substitua a linha<li>por este código:<li @onclick="@(() => ShowConfigurePizzaDialog(special))" style="background-image: url('@special.ImageUrl')">Quando um cliente seleciona uma pizza, o servidor executa o método
ShowConfigurePizzaDialogque cria uma pizza com os dados especiais da pizza e define a variávelshowingConfigureDialogcomotrue.A página precisa de uma maneira de exibir o novo componente
ConfigurePizzaDialog. Adicione este código acima do bloco@code:@if (showingConfigureDialog) { <ConfigurePizzaDialog Pizza="configuringPizza" /> }Todo o ficheiro
index.razordeverá ficar 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.
Lidar com 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.
Pare 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 Services. 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; } }Você percebe que há um código atualmente no componente index.razor que podemos mover para a nova classe. O próximo passo é disponibilizar esse serviço no aplicativo.
No explorador de ficheiros, selecione Program.cs.
Na parte do arquivo com as linhas que começam com
builder.Services., adicione esta linha:builder.Services.AddScoped<OrderState>();A partir do exercício anterior, adicionamos nosso contexto de banco de dados aqui. Este código adiciona o novo serviço
OrderState. Com esse código em vigor, agora podemos usá-lo no componenteindex.razor.Adicione a seguinte
usingdiretiva à parte superior do arquivo. Esta diretiva resolve quaisquer referências àOrderStateclasse:using BlazingPizza.Services;No explorador de ficheiros, expanda Páginas e, em seguida, selecione Index.razor.
Na parte superior do ficheiro, em
@inject NavigationManager NavigationManager, adicione este código:@using BlazingPizza.Services @inject OrderState OrderStateRemova
configuringPizza,showingConfigureDialogeShowConfigurePizzaDialog()do bloco@code. Agora deve ser 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 sempre que o código faz referência aos elementos excluídos.
Altere a chamada de
ShowConfigurePizzaDialog(special))para utilizar a versão OrderState:<li @onclick="@(() => OrderState.ShowConfigurePizzaDialog(special))" style="background-image: url('@special.ImageUrl')">Altere a referência ao booleano
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 deve ver nenhuma diferença. A caixa de diálogo é exibida como antes.
Cancelar e fazer pedidos de pizza
Você pode notar que há dois métodos na classe OrderState que ainda não são usados. Os CancelConfigurePizzaDialog métodos e ConfirmConfigurePizzaDialog fecham a caixa de diálogo e adicionam a pizza a um Order objeto assim que o cliente confirma o pedido. Vamos conectar esses métodos aos botões de diálogo de configuração.
Pare o aplicativo se ele ainda estiver em execução.
No explorador de ficheiros, expanda Partilhado. Em seguida, selecione ConfigurePizzaDialog.razor.
No bloco
@code, adicione dois novos parâmetros:@code { [Parameter] public Pizza Pizza { get; set; } [Parameter] public EventCallback OnCancel { get; set; } [Parameter] public EventCallback OnConfirm { get; set; } } `` `Agora, as diretivas
@onclickpodem ser adicionadas aos botões. 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>O último passo é passar os métodos
OrderStatepara cancelar e confirmar pedidos. No explorador de ficheiros, expanda Páginas. Em seguida, selecione Index.razor.Altere o código da chamada para o 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 é alterado. Adicionaremos estes recursos no próximo exercício.