Ejercicio: Uso de una biblioteca de JavaScript en una aplicación de Blazor

Completado

Después de que un cliente agregue una pizza a su pedido, puede seleccionar un icono X para quitarla del pedido sin confirmación. Para evitar que los clientes quiten accidentalmente pizzas de sus pedidos, la empresa de pizzas quiere que agregue un aviso de confirmación para la eliminación de artículos.

La empresa de pizzas también quiere que los clientes vean el estado del pedido en tiempo real. Debe actualizar la página de detalles del pedido para consultar continuamente el estado de dicho pedido y proporcionar a los clientes comentarios sobre la actualziación de la página.

En este ejercicio, ampliará la aplicación existente de la empresa de entrega de pizzas mediante la interoperabilidad de JS desde un componente de Blazor para llamar a JavaScript en el lado cliente. Se integra con una biblioteca de JavaScript de terceros para mejorar el elemento emergente de cancelación y llamar a un método de Blazor desde JavaScript para obtener el estado en tiempo real de un pedido de cliente.

Clonación de la aplicación existente

Para usar Blazor, asegúrate de que tienes instalado el SDK de .NET 8.0. Para obtener más información, consulte Comprobación de que todo está instalado correctamente.

  1. Abra Visual Studio Code y abra un terminal integrado; para ello, seleccione Terminal>Nuevo terminal en el menú principal.

  2. En el terminal, cambie al directorio a donde desea crear el proyecto.

  3. Ejecute el siguiente comando para clonar la aplicación de GitHub en un subdirectorio local.

    git clone https://github.com/MicrosoftDocs/mslearn-build-interactive-components-blazor.git BlazingPizza
    
  4. En la barra de menús superior, seleccione Archivo>Abrir carpeta.

  5. En el cuadro de diálogo Abrir carpeta, vaya a la carpeta BlazingPizza y elija Seleccionar carpeta.

    Si Visual Studio Code le pregunta sobre los recursos que faltan o las dependencias sin resolver, seleccione o Restaurar.

  6. Para ejecutar la aplicación y comprobar que todo funciona correctamente, presione F5 o seleccione Ejecutar>Iniciar depuración.

  7. En la aplicación web, seleccione algunas pizzas y agréguelas al pedido. Con unas cuantas pizzas en la lista de pedidos, seleccione la X junto a una de las pizzas y compruebe que el artículo desaparece sin preguntar.

  8. Presione Mayús+F5 o seleccione Ejecutar>Detener depuración para detener la aplicación.

Refactorización del proceso de un pedido

Para usar la interoperabilidad de JavaScript, debe inyectar la abstracción IJSRuntime.

  1. En el Explorador de Visual Studio Code, expanda Páginas y, después, seleccione Index.razor.

  2. En el archivo Index.razor, después de la instrucción @inject OrderState OrderState, agregue la inserción IJSRuntime como se indica a continuación.

    @inject OrderState OrderState
    @inject IJSRuntime JavaScript
    
  3. Actualmente, el evento onclick de la funcionalidad de eliminación de pizzas llama al método OrderState.RemoveConfiguredPizza(configuredPizza)) directamente. Reemplace el elemento <a @onclick="@(() => OrderState.RemoveConfiguredPizza(configuredPizza))" class="delete-item">❌</a> entero por el código siguiente:

    <button type="button" class="close text-danger" aria-label="Close"
         @onclick="@(async () => await RemovePizzaConfirmation(configuredPizza))">
         <span aria-hidden="true">&times;</span>
    </button>
    
  4. En la directiva @code al final del archivo, agregue un nuevo método para llamar a la función nativa de JavaScript confirm. Si el cliente selecciona Aceptar en el símbolo del sistema, el método llama a OrderState.RemoveConfiguredPizza para quitar la pizza del pedido. De lo contrario, la pizza permanece en el pedido.

    async Task RemovePizzaConfirmation(Pizza removePizza)
    {
        if (await JavaScript.InvokeAsync<bool>(
            "confirm",
            $"""Do you want to remove the "{removePizza.Special!.Name}" from your order?"""))
        {
            OrderState.RemoveConfiguredPizza(removePizza);
        }
    }
    

    El servidor usa el método IJSRuntime.InvokeAsync para llamar a la función confirm en el lado cliente. La respuesta de la llamada devuelve un valor bool. Si el resultado del cuadro de diálogo de confirmación es true, la pizza se quita del pedido.

  5. Presione F5 o seleccione Ejecutar>Iniciar depuración.

  6. En la aplicación, agregue algunas pizzas al pedido.

  7. Con algunas pizzas en el pedido, seleccione la X junto a una de las pizzas. Aparece un cuadro de diálogo de confirmación estándar de JavaScript.

    Screenshot of the default JavaScript confirm dialog.

  8. Seleccione Aceptar y compruebe que la pizza se ha quitado del pedido. Seleccione X junto a otra pizza, seleccione Cancelar en el cuadro de diálogo confirmar y compruebe que la pizza permanece en el pedido.

  9. Presione Mayús+F5 o seleccione Ejecutar>Detener depuración para detener la aplicación.

Adición de una biblioteca de JavaScript de terceros a una aplicación de Blazor

La empresa de pizzas quiere texto más claro en los botones del cuadro de diálogo confirmar y desea usar su personalización de marca y estilo en el cuadro de diálogo. Después de una investigación, decide usar una pequeña biblioteca de JavaScript denominada SweetAlert como un buen reemplazo para el cuadro de diálogo estándar.

  1. En el Explorador de Visual Studio Code, expanda Páginas y, después, seleccione _Host.cshtml.

  2. Al final del archivo _Host.cshtml, después de la línea <script src="_framework/blazor.server.js"></script> pero antes de la línea </body>, agregue el siguiente elemento script para incluir la biblioteca SweetAlert.

    <script src="https://cdn.jsdelivr.net/npm/sweetalert@latest/dist/sweetalert.min.js"></script>
    

    La biblioteca SweetAlert ya está disponible para llamar en el lado cliente.

  3. Para usar la nueva biblioteca, actualice el método RemovePizzaConfirmation en el archivo Index.razor como se indica a continuación.

    async Task RemovePizzaConfirmation(Pizza removePizza)
    {
        var messageParams = new
        {
            title = "Remove Pizza?",
            text = $"""Do you want to remove the "{removePizza.Special!.Name}" from your order?""",
            icon = "warning",
            buttons = new
            {
                abort = new { text = "No, leave it in my order", value = false },
                confirm = new { text = "Yes, remove pizza", value = true }
            },
            dangerMode = true
        };
    
        if (await JavaScript.InvokeAsync<bool>("swal", messageParams))
        {
            OrderState.RemoveConfiguredPizza(removePizza);
        }
    }
    

    El nombre "swal" es el identificador para la función de JavaScript que procede de la referencia sweetalert.js de terceros. El código para llamar a la función swal es similar a confirm. La mayor parte de la actualización está en cómo la función recibe los parámetros. SweetAlert acepta un objeto JSON que incluye toda la configuración que necesita.

  4. En Visual Studio Code, presione F5 o seleccione Ejecutar>Iniciar depuración.

  5. Compruebe que el cuadro de diálogo confirm ahora tiene dos botones que dicen No, dejarlo en mi pedido y Sí, quitar la pizza y que funcionan según lo previsto.

    Screenshot showing the SweetAlert dialog box.

  6. Presione Mayús+F5 o seleccione Ejecutar>Detener depuración para detener la aplicación.

Actualización de la página de pedido para mostrar el estado del pedido en tiempo real

Una vez que un cliente realiza un pedido de pizza, la página Mis pedidos usa el componente OrderDetail para mostrar el estado actual del pedido. La empresa de pizzas quiere que los clientes vean el estado del pedido en tiempo real. Actualizará el componente para llamar a un método de .NET desde JavaScript que obtiene continuamente el estado del pedido hasta que el estado indica que se ha entregado.

  1. En el Explorador de Visual Studio Code, expanda Páginas y, después, seleccione OrderDetail.razor.

  2. En el archivo OrderDetail.razor, agregue la siguiente declaración en la parte superior del componente, en la última instrucción @inject.

    @implements IDisposable
    

    Esta declaración @implements le permite definir un método Dispose.

  3. Agregue un indicador de progreso a la página para proporcionar al cliente comentarios sobre la actualización de la página. En <div class="track-order-details">, sobre de la instrucción @foreach, agregue el código siguiente:

    @if (IsOrderIncomplete)
    {
        <div class="spinner-grow text-danger float-right" role="status">
            <span class="sr-only">Checking your order status...</span>
        </div>
    }
    
  4. En la directiva @code, bajo la declaración de la propiedad OrderId, agregue los siguientes miembros.

    bool IsOrderIncomplete =>
        orderWithStatus is null || orderWithStatus.IsDelivered == false;
    
    PeriodicTimer timer = new(TimeSpan.FromSeconds(3));
    
  5. Reemplace el método OnParametersSetAsync existente por el código siguiente:

    protected override async Task OnParametersSetAsync() =>
        await GetLatestOrderStatusUpdatesAsync();
    

    El código llama ahora al método GetLatestOrderStatusUpdatesAsync para actualizar el estado del pedido.

  6. Agregue los métodos siguientes después del método actualizado OnParametersSetAsync.

    protected override Task OnAfterRenderAsync(bool firstRender) =>
        firstRender ? StartPollingTimerAsync() : Task.CompletedTask;
    
    async Task GetLatestOrderStatusUpdatesAsync()
    {
        try
        {
            orderWithStatus = await HttpClient.GetFromJsonAsync<OrderWithStatus>(
                $"{NavigationManager.BaseUri}orders/{OrderId}");
        }
        catch (Exception ex)
        {
            invalidOrder = true;
            Console.Error.WriteLine(ex);
        }
    }
    
    async Task StartPollingTimerAsync()
    {
        while (IsOrderIncomplete && await timer.WaitForNextTickAsync())
        {
            await GetLatestOrderStatusUpdatesAsync();
            StateHasChanged();
        }
    }
    
    public void Dispose() => timer.Dispose();
    

    El componente OrderDetail inicia el sondeo después de que la página se representa y lo detiene cuando se entrega el pedido. Mientras que el estado del pedido esté incompleto, la función StartPollingTimerAsync usa PeriodicTimer para esperar de forma asincrónica el tic siguiente. Cuando el pedido se entrega, se quita el indicador giratorio animado y la página muestra el estado final del pedido.

  7. En Visual Studio Code, presione F5 o seleccione Ejecutar>Iniciar depuración.

  8. En la aplicación, pida una pizza. Vaya a la pantalla Mis pedidos y compruebe que el punto rojo animado aparece mientras el pedido está incompleto y desaparece cuando el estado muestra Entregado.

    Animation showing the order status changing in real-time.

  9. Presione Mayús+F5 o seleccione Ejecutar>Detener depuración para detener la aplicación.