Uso compartido de datos en aplicaciones Blazor

Completado

Blazor incluye varias maneras de compartir información entre los componentes. Puede usar parámetros de componente o parámetros en cascada para enviar valores de un componente primario a un componente secundario. El patrón AppState es otro enfoque que puede usar para almacenar valores y acceder a ellos desde cualquier componente de la aplicación.

Imagine que trabaja en el nuevo sitio web de entrega de pizzas. Se deben mostrar varias pizzas en la página principal de la misma manera. Le gustaría mostrar las pizzas mediante la representación de un componente secundario para cada pizza. Ahora, quiere pasar un id. a ese componente secundario que determina la pizza que se mostrará. También quiere almacenar y mostrar un valor en varios componentes que muestre el número total de pizzas que ha vendido hoy.

En esta unidad, aprenderá tres técnicas diferentes que puede usar para compartir valores entre dos o más componentes de Blazor.

Uso compartido de información con otros componentes mediante parámetros de componente

En una aplicación web Blazor, cada componente representa una parte de HTML. Algunos componentes representan una página completa, pero otros representan fragmentos más pequeños de marcado, como una tabla, un formulario o un único control. Si el componente representa solo una sección de marcado, debe usarlo como componente secundario dentro de un componente primario. El componente secundario también puede ser primario para otros componentes más pequeños que se representan dentro de él. Los componentes secundarios también se conocen como componentes anidados.

En esta jerarquía de componentes primarios y secundarios, puede compartir información entre ellos mediante los parámetros de componente. Defina estos parámetros en los componentes secundarios y, a continuación, establezca sus valores en el elemento primario. Por ejemplo, si tiene un componente secundario que muestra fotos de pizza, puede usar un parámetro de componente para pasar el id. de pizza. El componente secundario busca la pizza a partir del id. y obtiene imágenes y otros datos. Si quiere mostrar muchas pizzas diferentes, puede usar este componente secundario varias veces en la misma página primaria, pasando un id. diferente a cada elemento secundario.

Empiece por definir el parámetro de componente en el componente secundario. Se define como una propiedad pública de C# y se decora con el atributo [Parameter]:

<h2>New Pizza: @PizzaName</h2>

<p>@PizzaDescription</p>

@code {
    [Parameter]
    public string PizzaName { get; set; }
    
    [Parameter]
    public string PizzaDescription { get; set; } = "The best pizza you've ever tasted."
}

Dado que los parámetros de componente son miembros del componente secundario, puede representarlos en el código HTML mediante el símbolo reservado @ de Blazor, seguido de su nombre. Además, el código anterior especifica un valor predeterminado para el parámetro PizzaDescription. Este valor se representa si el componente primario no pasa un valor. De lo contrario, se reemplaza por el valor pasado desde el elemento primario.

También puede usar clases personalizadas en el proyecto como parámetros de componente. Considere esta clase que describe un ingrediente:

public class PizzaTopping
{
    public string Name { get; set; }
    public string Ingredients { get; set; }
}

Puede usarlo como parámetro de componente de la misma manera que un valor de parámetro, accediendo a propiedades individuales de la clase mediante la sintaxis de punto:

<h2>New Topping: @Topping.Name</h2>

<p>Ingredients: @Topping.Ingredients</p>

@code {
    [Parameter]
    public PizzaTopping Topping { get; set; }
}

En el componente primario, establezca los valores de parámetro mediante atributos de las etiquetas del componente secundario. Establezca directamente los componentes simples. Con un parámetro basado en una clase personalizada, use código C# en línea para crear una nueva instancia de esa clase y establecer sus valores:

@page "/pizzas-toppings"

<h1>Our Latest Pizzas and Topping</h1>

<Pizza PizzaName="Hawaiian" PizzaDescription="The one with pineapple" />

<PizzaTopping Topping="@(new PizzaTopping() { Name = "Chilli Sauce", Ingredients = "Three kinds of chilli." })" />

Uso compartido de información mediante parámetros en cascada

Los parámetros de componente funcionan bien cuando se desea pasar un valor al elemento secundario inmediato de un componente. Las cosas se complican cuando se tiene una jerarquía profunda con hijos de hijos, y así sucesivamente. Los parámetros de componente no se pasan automáticamente a componentes descendientes del secundario desde componentes antecesores ni más abajo en la jerarquía. Para controlar este problema de forma elegante, Blazor incluye parámetros en cascada. Cuando se establece el valor de un parámetro en cascada en un componente, su valor está disponible automáticamente para todos los componentes descendientes en cualquier profundidad.

En el componente primario, el uso de la etiqueta <CascadingValue> especifica la información que se transmitirá en cascada a todos los descendientes. Esta etiqueta se implementa como un componente integrado de Blazor. Cualquier componente que se represente dentro de esa etiqueta podrá acceder al valor.

@page "/specialoffers"

<h1>Special Offers</h1>

<CascadingValue Name="DealName" Value="Throwback Thursday">
    <!-- Any descendant component rendered here will be able to access the cascading value. -->
</CascadingValue>

En los componentes descendientes, puede acceder al valor en cascada mediante los miembros de componente y su decoración con el atributo [CascadingParameter].

<h2>Deal: @DealName</h2>

@code {
    [CascadingParameter(Name="DealName")]
    private string DealName { get; set; }
}

Por lo tanto, en este ejemplo, la etiqueta <h2> tiene el contenido Deal: Throwback Thursday porque ese valor en cascada lo estableció un componente antecesor.

Nota

En cuanto a los parámetros de componente, puede pasar objetos como parámetros en cascada si tiene requisitos más complejos.

En el ejemplo anterior, el atributo Name del elemento primario identifica el valor en cascada, que coincide con el valor Name del atributo [CascadingParameter]. Opcionalmente, puede omitir estos nombres, en cuyo caso los atributos se emparejan por tipo. Esto funciona bien cuando solo tiene un parámetro de ese tipo. Si quiere transferir en cascada dos valores de cadena diferentes, debe usar nombres de parámetro para evitar cualquier ambigüedad.

Uso compartido de información mediante AppState

Otro enfoque para compartir información entre distintos componentes es usar el patrón AppState. Cree una clase que defina las propiedades que quiere almacenar y regístrela como un servicio con ámbito. En cualquier componente donde quiera establecer o usar los valores de AppState, inserte el servicio y, a continuación, podrá acceder a sus propiedades. A diferencia de los parámetros de componente y los parámetros en cascada, los valores de AppState están disponibles para todos los componentes de la aplicación, incluso los componentes que no son elementos secundarios del componente que almacenaba el valor.

Por ejemplo, considere la posibilidad de crear una clase que almacena un valor sobre las ventas:

public class PizzaSalesState
{
    public int PizzasSoldToday { get; set; }
}

Ahora, agregaría la clase como un servicio con ámbito, en el archivo Program.cs:

...
// Add services to the container
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();

// Add the AppState class
builder.Services.AddScoped<PizzaSalesState>();
...

Ahora, en cualquier componente donde quiera establecer o recuperar valores de AppState, puede inyectar la clase y, a continuación, acceder a las propiedades:

@page "/"
@inject PizzaSalesState SalesState

<h1>Welcome to Blazing Pizzas</h1>

<p>Today, we've sold this many pizzas: @SalesState.PizzasSoldToday</p>

<button @onclick="IncrementSales">Buy a Pizza</button>

@code {
    private void IncrementSales()
    {
        SalesState.PizzasSoldToday++;
    }
}

Nota

Este código implementa un contador que se incrementa cuando el usuario selecciona en un botón, muy parecido al ejemplo del Tutorial de Blazor: compilación de la primera aplicación Blazor. La diferencia es que, en este caso, dado que hemos almacenado el valor del contador en un servicio con ámbito AppState, el recuento persiste entre cargas de página y otros usuarios pueden verlo.

¡En la unidad siguiente, lo probará usted mismo!

Comprobar los conocimientos

1.

Los componentes de Blazor pueden recibir entrada mediante dos tipos de parámetros. ¿Cuáles son?

2.

AppState se puede registrar con el localizador de servicios mediante una estas instrucciones, ¿cuál?