Compartilhar dados em aplicativos Blazor
- 7 minutos
Blazor inclui várias maneiras de compartilhar informações entre componentes. Você pode usar parâmetros de componente ou parâmetros em cascata para enviar valores de um componente pai para um componente filho. O padrão AppState é outra abordagem que você pode usar para armazenar valores e acessá-los de qualquer componente no aplicativo.
Suponha que você esteja trabalhando no novo site de entrega de pizza. Várias pizzas devem ser exibidas na página inicial da mesma maneira. Você deseja exibir as pizzas renderizando um componente infantil para cada pizza. Agora, você deseja passar um ID para esse componente filho que determina a pizza que ele exibe. Você também deseja armazenar e exibir um valor em vários componentes que mostra o número total de pizzas que você vendeu hoje.
Nesta unidade, você aprende três técnicas diferentes que você pode usar para compartilhar valores entre dois ou mais componentes Blazor.
Compartilhando informações com outros componentes usando parâmetros de componentes
Em um aplicativo Web Blazor, cada componente renderiza uma parte do HTML. Alguns componentes renderizam uma página completa, mas outros renderizam fragmentos menores de marcação, como uma tabela, um formulário ou um único controle. Se o componente renderizar apenas uma seção de marcação, você deverá usá-lo como um componente filho dentro de um componente pai. O seu componente filho também pode ser pai de outros componentes mais pequenos que são renderizados dentro dele. Os componentes filho também são conhecidos como componentes aninhados.
Nessa hierarquia de componentes pai e filho, você pode compartilhar informações entre eles usando parâmetros de componente. Defina estes parâmetros nos componentes filho e, em seguida, defina os valores destes no pai. Por exemplo, se tiveres um componente filho que exibe fotos de pizza, podes usar um parâmetro de componente para passar o identificador da pizza. O componente filho localiza a pizza pelo ID e obtém fotos e outros dados. Se pretender exibir muitas pizzas diferentes, pode usar este componente filho várias vezes na mesma página principal, passando um ID diferente para cada componente filho.
Comece por definir o parâmetro "component" dentro do componente filho. Define-o como uma propriedade pública C# e decora-o com o [Parameter] atributo:
<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."
}
Como os parâmetros do componente são membros do componente filho, pode-se renderizá-los no seu HTML usando o símbolo @ reservado de Blazor, seguido do seu nome. Além disso, o código anterior especifica um valor padrão para o parâmetro PizzaDescription. Esse valor é renderizado se o componente pai não passar um valor. Caso contrário, o valor passado do pai o substituirá.
Você também pode usar classes personalizadas em seu projeto como parâmetros de componente. Considere esta classe que descreve uma cobertura:
public class PizzaTopping
{
public string Name { get; set; }
public string Ingredients { get; set; }
}
Você pode usar isso como um parâmetro de componente da mesma forma que um valor de parâmetro para acessar propriedades individuais da classe usando a sintaxe de pontos:
<h2>New Topping: @Topping.Name</h2>
<p>Ingredients: @Topping.Ingredients</p>
@code {
[Parameter]
public PizzaTopping Topping { get; set; }
}
No componente pai, você define valores de parâmetro usando atributos das tags do componente filho. Você define componentes simples diretamente. Com um parâmetro baseado em uma classe personalizada, você usa o código C# embutido para criar uma nova instância dessa classe e definir seus 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." })" />
Compartilhar informações usando parâmetros em cascata
Os parâmetros do componente funcionam bem quando você deseja passar um valor para o filho imediato de um componente. As coisas se tornam estranhas quando você tem uma hierarquia profunda com filhos de crianças e assim por diante. Os parâmetros dos componentes não são passados automaticamente para os componentes dos netos a partir dos componentes ancestrais ou mais abaixo na hierarquia. Para lidar com esse problema elegantemente, Blazor inclui parâmetros em cascata. Quando você define o valor de um parâmetro em cascata em um componente, seu valor fica automaticamente disponível para todos os componentes descendentes em qualquer profundidade.
No componente pai, o uso da etiqueta <CascadingValue> especifica as informações que serão propagadas para todos os descendentes. Esta tag é implementada como um componente Blazor integrado. Qualquer componente renderizado dentro dessa tag é capaz de acessar o 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>
Nos componentes descendentes, você pode acessar o valor em cascata usando membros do componente e decorando-os com o atributo [CascadingParameter].
<h2>Deal: @DealName</h2>
@code {
[CascadingParameter(Name="DealName")]
private string DealName { get; set; }
}
Portanto, neste exemplo, a <h2> tag tem o conteúdo Deal: Throwback Thursday porque um componente ancestral define esse valor em cascata.
Note
Quanto aos parâmetros de componentes, você pode passar objetos como parâmetros em cascata se tiver requisitos mais complexos.
No exemplo anterior, o atributo Name no pai identifica o valor em cascata, que é correspondido com o valor Name no atributo [CascadingParameter]. Opcionalmente, pode omitir esses nomes, neste caso, os atributos são associados por tipo. Omitir o nome funciona bem quando você tem apenas um parâmetro desse tipo. Se quiseres concatenar dois valores de texto diferentes, deves usar nomes de parâmetros para evitar qualquer ambiguidade.
Compartilhar informações usando AppState
Outra abordagem para compartilhar informações entre diferentes componentes é usar o padrão AppState. Você cria uma classe que define as propriedades que deseja armazenar e a registra como um serviço com escopo. Em qualquer componente onde você deseja definir ou usar os valores AppState, você injeta o serviço e, em seguida, você pode acessar suas propriedades. Ao contrário dos parâmetros de componente e parâmetros em cascata, os valores no AppState estão disponíveis para todos os componentes no aplicativo, mesmo os componentes que não são filhos do componente que armazenou o valor.
Como exemplo, considere esta classe que armazena um valor sobre vendas:
public class PizzaSalesState
{
public int PizzasSoldToday { get; set; }
}
Você adicionaria a classe como um serviço com escopo no arquivo Program.cs :
...
// Add services to the container
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
// Add the AppState class
builder.Services.AddScoped<PizzaSalesState>();
...
Agora, em qualquer componente em que você queira definir ou recuperar valores AppState, você pode injetar a classe e, em seguida, acessar propriedades:
@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++;
}
}
Note
Este código implementa um contador que aumenta quando o usuário seleciona um botão, muito parecido com o exemplo no Blazor Tutorial - Build your first Blazor app. A diferença é que, nesse caso, armazenamos o valor do contador em um serviço com escopo AppState. Nossa classe de serviço com escopo permite que a contagem persista nos carregamentos de página e outros usuários podem vê-la.
Na próxima unidade, você vai tentar você mesmo!