Compartilhar dados em aplicativos Blazor
- 7 minutos
O 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 home page da mesma maneira. Você deseja exibir as pizzas renderizando um componente filho para cada pizza. Agora, você deseja passar uma ID para esse componente filho que determina a pizza exibida por ele. Você também deseja armazenar e exibir um valor em vários componentes que mostra o número total de pizzas vendidas hoje.
Nesta unidade, você aprenderá três técnicas diferentes que você pode usar para compartilhar valores entre dois ou mais componentes do Blazor.
Compartilhando informações com outros componentes usando parâmetros de componente
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 seu componente renderizar apenas uma seção de marcação, use-o como um componente filho dentro de um componente pai. Seu componente filho também pode ser pai de outros componentes menores 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 os parâmetros em componentes filho e defina seus valores no pai. Por exemplo, se você tiver um componente filho que exiba fotos de pizza, poderá usar um parâmetro de componente para passar a ID da pizza. O componente filho pesquisa a pizza a partir da ID e obtém imagens e outros dados. Se você quiser exibir várias pizzas diferentes, poderá usar esse componente filho várias vezes na mesma página pai, passando uma ID diferente para cada filho.
Comece definindo o parâmetro de componente no componente filho. Defina-a como uma propriedade pública C# e decore-a 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 de componente são membros do componente filho, você pode renderizá-los em seu HTML usando o símbolo reservado @ do Blazor, seguido pelo nome. Além disso, o código anterior especifica um valor padrão para o PizzaDescription parâmetro. Esse valor é renderizado se o componente pai não transmitir um valor. Caso contrário, o valor passado pelo pai o substituirá.
Você também pode usar classes personalizadas em seu projeto como parâmetros de componente. Considere esta classe que descreve um recheio:
public class PizzaTopping
{
public string Name { get; set; }
public string Ingredients { get; set; }
}
Você pode usá-lo 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 ponto:
<h2>New Topping: @Topping.Name</h2>
<p>Ingredients: @Topping.Ingredients</p>
@code {
[Parameter]
public PizzaTopping Topping { get; set; }
}
No componente pai, você define os valores dos parâmetros usando os atributos dos elementos 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 de componente funcionam bem quando você deseja passar um valor para o filho imediato de um componente. As coisas se complicam quando você tem uma hierarquia profunda com filhos de filhos e assim por diante. Os parâmetros do componente não são transmitidos automaticamente para os componentes neto a partir dos componentes ancestrais ou mais para baixo 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 para qualquer profundidade.
No componente pai, o uso da tag <CascadingValue> especifica as informações que serão propagadas para todos os descendentes. Essa tag é implementada como um componente Blazor integrado. Qualquer componente renderizado dentro dessa tag pode 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, é possível acessar o valor em cascata usando membros de componentes 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> marca tem o conteúdo Deal: Throwback Thursday porque um componente ancestral define esse valor em cascata.
Note
Quanto aos parâmetros de componente, você pode passar objetos como parâmetros em cascata se tiver requisitos mais complexos.
No exemplo anterior, o atributo Name no elemento pai identifica o valor em cascata, que é correspondido ao valor Name no atributo [CascadingParameter]. Opcionalmente, você pode omitir esses nomes. Nesse caso, os atributos são correspondidos por tipo. Omitir o nome funciona bem quando você tem apenas um parâmetro desse tipo. Se você quiser colocar em cascata dois valores de cadeia de caracteres diferentes, deverá usar nomes de parâmetro para evitar qualquer ambiguidade.
Compartilhar informações usando AppState
Outra abordagem para compartilhar informações entre diferentes componentes é usar o padrão AppState. Crie uma classe que defina as propriedades que deseja armazenar e registre-a como um serviço com escopo. Em qualquer componente em que você deseja definir ou usar os valores appState, você injeta o serviço e, em seguida, pode acessar suas propriedades. Ao contrário dos parâmetros de componente e dos 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.
Por exemplo, considere essa 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ê deseja definir ou recuperar valores AppState, você pode injetar a classe e acessar as 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
Esse código implementa um contador que incrementa quando o usuário seleciona um botão, assim como o exemplo no Tutorial blazor – Criar seu primeiro aplicativo Blazor. 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 entre cargas de página e outros usuários podem vê-la.
Na próxima unidade, você mesmo tentará!