Ejercicio: Uso compartido de datos en aplicaciones Blazor
Ahora que la aplicación está conectada a una base de datos, es el momento de agregar la capacidad de pedir y configurar la pizza de un cliente.
A Blazing Pizza le gustaría crear la capacidad para que los clientes cambien el tamaño de sus pizzas especiales. Debe almacenar el pedido y ha elegido almacenar el estado de la aplicación en un servicio de contenedor.
En este ejercicio, pasará datos a un nuevo componente de configuración de pedido y verá cómo almacenar el estado de la aplicación en un servicio con ámbito OrderState.
Adición de un nuevo cuadro de diálogo de configuración de pedido
Detenga la aplicación si todavía está en ejecución.
En Visual Studio Code, haga clic con el botón derecho en la carpeta Compartido y seleccione Nuevo archivo.
Escriba ConfigurePizzaDialog.razor como nombre de archivo.
Escriba este código para la interfaz de usuario del nuevo 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 es un cuadro de diálogo que muestra la pizza especial seleccionada y permite al cliente seleccionar el tamaño de la pizza.
El componente necesita una pizza especial del componente de página de índice para acceder a los valores de miembro de una pizza.
Agregue el bloque
@code
de Blazor para permitir que los parámetros se pasen al componente:@code { [Parameter] public Pizza Pizza { get; set; } }
Pedido de una pizza
Cuando un cliente selecciona una pizza, el cuadro de diálogo debe permitirle cambiar el tamaño de la pizza. Vamos a mejorar el control index.razor para agregar esta interactividad.
En el explorador de archivos, expanda Páginas y, después, seleccione index.razor.
Agregue el código siguiente en el bloque
@code
en la variableList<PizzaSpecial>
.Pizza configuringPizza; bool showingConfigureDialog;
Agregue código para crear una pizza en el método
OnInitializedAsync()
:void ShowConfigurePizzaDialog(PizzaSpecial special) { configuringPizza = new Pizza() { Special = special, SpecialId = special.Id, Size = Pizza.DefaultSize }; showingConfigureDialog = true; }
Permita que la página web llame al método
ShowConfigurePizzaDialog
del lado servidor permitiendo a los clientes seleccionar una etiqueta<li>
de pizzas. Reemplace la línea<li>
por este código:<li @onclick="@(() => ShowConfigurePizzaDialog(special))" style="background-image: url('@special.ImageUrl')">
Cuando un cliente selecciona una pizza, el servidor ejecuta el método
ShowConfigurePizzaDialog
que crea una pizza con los datos de la pizza especial y establece la variableshowingConfigureDialog
entrue
.La página necesita una manera de mostrar el nuevo componente
ConfigurePizzaDialog
. Agregue este código justo encima del bloque@code
:@if (showingConfigureDialog) { <ConfigurePizzaDialog Pizza="configuringPizza" /> }
Todo el archivo
index.razor
debería tener el aspecto de este ejemplo:@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; } }
Seleccione F5 o Ejecutar. A continuación, seleccione Iniciar depuración.
Seleccione una pizza y observe que aparece el nuevo cuadro de diálogo.
Control del estado de un pedido
Por el momento, la aplicación muestra el cuadro de diálogo de configuración, pero no permite cancelar ni pasar a pedir la pizza. Para administrar el estado del pedido, agregará un nuevo servicio de contenedor del estado del pedido.
Detenga la aplicación si todavía está en ejecución.
Cree una nueva carpeta en la carpeta BlazingPizza. Asígnele el nombre Services.
Cree un nuevo archivo en la carpeta Services. Asígnelo el nombre OrderState.cs.
Escriba este código para la clase:
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; } }
Verá que hay código actualmente en el componente index.razor que podemos mover a la nueva clase. El siguiente paso es hacer que este servicio esté disponible en la aplicación.
En el explorador de archivos, seleccione Program.cs.
En la parte del archivo con las líneas que comienzan por
builder.Services.
, agregue esta línea:builder.Services.AddScoped<OrderState>();
Hemos agregado aquí el contexto de la base de datos del ejercicio anterior. Este código agrega el nuevo servicio
OrderState
. Con este código en su lugar, ahora podemos usarlo en el componenteindex.razor
.Agregue la siguiente directiva
using
a la parte superior del archivo para resolver la claseOrderState
:using BlazingPizza.Services;
En el explorador de archivos, expanda Páginas y, después, seleccione index.razor.
En la parte superior del archivo, en
@inject NavigationManager NavigationManager
, agregue este código:@using BlazingPizza.Services @inject OrderState OrderState
Quite
configuringPizza
,showingConfigureDialog
yShowConfigurePizzaDialog()
del@code
bloque. Debería ser parecido a este:@code { List<PizzaSpecial> specials = new List<PizzaSpecial>(); protected override async Task OnInitializedAsync() { specials = await HttpClient.GetFromJsonAsync<List<PizzaSpecial>>(NavigationManager.BaseUri + "specials"); } }
Ahora hay errores en los que todo el código hace referencia a lo que se ha eliminado.
Cambie la llamada a
ShowConfigurePizzaDialog(special))
para usar la versión OrderState:<li @onclick="@(() => OrderState.ShowConfigurePizzaDialog(special))" style="background-image: url('@special.ImageUrl')">
Cambie la referencia al booleano
showingConfigureDialog
:@if (OrderState.ShowingConfigureDialog)
Cambie el parámetro mediante
configuringPizza
:<ConfigurePizzaDialog Pizza="OrderState.ConfiguringPizza" />
Seleccione F5 o Ejecutar. A continuación, seleccione Iniciar depuración.
Si todo es correcto, no verá ninguna diferencia. El cuadro de diálogo se muestra como antes.
Realización y cancelación de pedidos de pizza
Es posible que haya observado en la clase OrderState dos métodos que aún no hemos usado. Los métodos CancelConfigurePizzaDialog
y ConfirmConfigurePizzaDialog
cierran el cuadro de diálogo y agregan la pizza a un objeto Order
si el cliente ha confirmado el pedido. Vamos a conectar estos métodos a los botones del cuadro de diálogo de configuración.
Detenga la aplicación si todavía está en ejecución.
En el explorador de archivos, expanda Compartido. A continuación, seleccione ConfigurePizzaDialog.razor.
En el bloque
@code
, agregue dos parámetros nuevos:@code { [Parameter] public Pizza Pizza { get; set; } [Parameter] public EventCallback OnCancel { get; set; } [Parameter] public EventCallback OnConfirm { get; set; } }
Ahora se pueden agregar directivas
@onclick
a los botones. Cambie el código actual de los botones del cuadro de diálogo a este marcado:<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>
El último paso es pasar nuestros métodos
OrderState
para cancelar y confirmar pedidos. En el explorador de archivos, expanda Páginas. Después, seleccione Index.razor.Cambie el código de la llamada al componente
ConfigurePizzaDialog
:<ConfigurePizzaDialog Pizza="OrderState.ConfiguringPizza" OnCancel="OrderState.CancelConfigurePizzaDialog" OnConfirm="OrderState.ConfirmConfigurePizzaDialog" />
Seleccione F5 o Ejecutar. A continuación, seleccione Iniciar depuración.
La aplicación ahora debe permitir que los clientes agreguen una pizza configurada a un pedido o lo cancelen. No tenemos ninguna manera de mostrar el pedido actual ni actualizar los precios cuando se cambia el tamaño de la pizza. Agregaremos estas características en el ejercicio siguiente.