Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
componente ASP.NET Core Blazor
Observação
Esta não é a versão mais recente deste artigo. Para ver a versão atual, consulte a versão .NET 10 deste artigo.
O componente QuickGrid é um componente Razor para exibir dados de maneira rápida e eficiente em formato tabular. O QuickGrid fornece um componente de grade de dados simples e conveniente para cenários comuns de renderização de grade e serve como uma arquitetura de referência e linha de base de desempenho para criar componentes de grade de dados. O QuickGrid é altamente otimizado e usa técnicas avançadas para obter o desempenho ideal de renderização.
Pacote
Adicione uma referência de pacote para o pacote Microsoft.AspNetCore.Components.QuickGrid.
Observação
Para obter diretrizes sobre como adicionar pacotes a aplicativos .NET, consulte os artigos em Instalar e gerenciar pacotes em Fluxo de trabalho de consumo de pacotes (documentação do NuGet). Confirme as versões corretas de pacote em NuGet.org.
Aplicativo de exemplo
Para várias demonstrações de QuickGrid, consulte o aplicativo de exemplo QuickGrid para Blazor. O site de demonstração é hospedado no GitHub Pages. O site carrega rapidamente graças à prerenderização estática usando o projeto GitHub mantido pela comunidade.
QuickGrid implementação
Para implementar um componente QuickGrid:
- Especifique as marcas para o componente
QuickGridna marcação Razor (<QuickGrid>...</QuickGrid>). - Identifique uma fonte de dados que possa ser consultada para a grelha. Use uma das seguintes fontes de dados:
-
Items: um valor anulável
IQueryable<TGridItem>, em queTGridItemé o tipo de dados representado por cada linha na grade. - ItemsProvider: um retorno de chamada que fornece dados para a grade.
-
Items: um valor anulável
-
Class: um nome de classe CSS opcional. Se fornecido, o nome da classe será incluído no atributo
classda tabela renderizada. -
Theme: um nome de tema (valor padrão:
default). Isso impacta quais regras de estilo correspondem à tabela. - Virtualize: se for true, a grade será renderizada com virtualização. Normalmente, isso é usado juntamente com a rolagem e faz com que a grade busque e renderize apenas os dados em torno do visor de rolagem atual. Isso pode melhorar muito o desempenho de rolagem em grandes conjuntos de dados. Se usar Virtualize, você deverá fornecer um valor para ItemSize e deverá garantir que cada linha seja renderizada com uma altura constante. Geralmente, é preferível não usar Virtualize se a quantidade de dados renderizados for pequena ou se você estiver usando a paginação.
- ItemSize: aplicável somente ao usar Virtualize. ItemSize define uma altura esperada em pixels para cada linha, permitindo que o mecanismo de virtualização busque o número correto de itens para corresponder ao tamanho da exibição e garantir uma rolagem precisa.
-
ItemKey: opcionalmente define um valor para
@keyem cada linha renderizada. Normalmente, é usado para especificar um identificador exclusivo, como um valor de chave primária, para cada item de dados. Isso permite que a grade preserve a associação entre elementos de linha e itens de dados com base em seus identificadores exclusivos, mesmo quando as instânciasTGridItemsão substituídas por novas cópias (por exemplo, após uma nova consulta no armazenamento de dados subjacente). Se não estiver definido,@keyserá a instânciaTGridItem. -
OverscanCount: define quantos itens adicionais serão renderizados antes e depois da região visível para reduzir a frequência de renderização durante a rolagem. Embora valores mais altos possam melhorar a suavidade da rolagem renderizando mais itens fora da tela, um valor mais alto também pode resultar em um aumento nos tempos de carga iniciais. É recomendável encontrar um equilíbrio com base no tamanho do conjunto de dados e nos requisitos de experiência do usuário. O valor padrão é
3. Disponível somente ao usar Virtualize. -
Pagination: opcionalmente vincula essa instância
TGridItema um modelo PaginationState, fazendo com que a grade busque e renderize apenas a página de dados atual. Normalmente, é usado em conjunto com um componente Paginator ou alguma outra lógica de interface do usuário que exiba e atualize a instância PaginationState fornecida. - No conteúdo filho QuickGrid (RenderFragment), especifique PropertyColumn<TGridItem,TProp>s, que representam colunas
TGridItemcujas células exibem os valores:- Property: define o valor a ser exibido nas células dessa coluna.
-
Format: opcionalmente especifica uma cadeia de caracteres de formato para o valor. Para usar Format, é preciso o tipo
TProppara implementar IFormattable. - Sortable: indica se os dados devem ser classificados por esta coluna. O valor padrão pode variar de acordo com o tipo de coluna. Por exemplo, um TemplateColumn<TGridItem> será ordenado se algum parâmetro SortBy for especificado.
-
InitialSortDirection: indica a direção de classificação se IsDefaultSortColumn for
true. - IsDefaultSortColumn: indica se essa coluna deve ser classificada por padrão.
- PlaceholderTemplate: se especificado, as grades virtualizadas usam esse modelo para renderizar células cujos dados não tenham sido carregados.
- HeaderTemplate: um modelo opcional para a célula de cabeçalho desta coluna. Se não for especificado, o modelo de cabeçalho padrão inclui o Title, juntamente com os botões de opções e indicadores de classificação aplicáveis.
- Title: texto do título da coluna. O título será renderizado automaticamente se HeaderTemplate não for usado.
- Especifique as marcas para o componente
QuickGridna marcação Razor (<QuickGrid>...</QuickGrid>). - Identifique uma fonte de dados que possa ser consultada para a grelha. Use uma das seguintes fontes de dados:
-
Items: um valor anulável
IQueryable<TGridItem>, em queTGridItemé o tipo de dados representado por cada linha na grade. - ItemsProvider: um retorno de chamada que fornece dados para a grade.
-
Items: um valor anulável
-
Class: um nome de classe CSS opcional. Se fornecido, o nome da classe será incluído no atributo
classda tabela renderizada. -
Theme: um nome de tema (valor padrão:
default). Isso impacta quais regras de estilo correspondem à tabela. - Virtualize: se for true, a grade será renderizada com virtualização. Normalmente, isso é usado juntamente com a rolagem e faz com que a grade busque e renderize apenas os dados em torno do visor de rolagem atual. Isso pode melhorar muito o desempenho de rolagem em grandes conjuntos de dados. Se usar Virtualize, você deverá fornecer um valor para ItemSize e deverá garantir que cada linha seja renderizada com uma altura constante. Geralmente, é preferível não usar Virtualize se a quantidade de dados renderizados for pequena ou se você estiver usando a paginação.
- ItemSize: aplicável somente ao usar Virtualize. ItemSize define uma altura esperada em pixels para cada linha, permitindo que o mecanismo de virtualização busque o número correto de itens para corresponder ao tamanho da exibição e garantir uma rolagem precisa.
-
ItemKey: opcionalmente define um valor para
@keyem cada linha renderizada. Normalmente, é usado para especificar um identificador exclusivo, como um valor de chave primária, para cada item de dados. Isso permite que a grade preserve a associação entre elementos de linha e itens de dados com base em seus identificadores exclusivos, mesmo quando as instânciasTGridItemsão substituídas por novas cópias (por exemplo, após uma nova consulta no armazenamento de dados subjacente). Se não estiver definido,@keyserá a instânciaTGridItem. -
Pagination: opcionalmente vincula essa instância
TGridItema um modelo PaginationState, fazendo com que a grade busque e renderize apenas a página de dados atual. Normalmente, é usado em conjunto com um componente Paginator ou alguma outra lógica de interface do usuário que exiba e atualize a instância PaginationState fornecida. - No conteúdo filho QuickGrid (RenderFragment), especifique PropertyColumn<TGridItem,TProp>s, que representam colunas
TGridItemcujas células exibem os valores:- Property: define o valor a ser exibido nas células dessa coluna.
-
Format: opcionalmente especifica uma cadeia de caracteres de formato para o valor. Para usar Format, é preciso o tipo
TProppara implementar IFormattable. - Sortable: indica se os dados devem ser classificados por esta coluna. O valor padrão pode variar de acordo com o tipo de coluna. Por exemplo, um TemplateColumn<TGridItem> será ordenado se algum parâmetro SortBy for especificado.
-
InitialSortDirection: indica a direção de classificação se IsDefaultSortColumn for
true. - IsDefaultSortColumn: indica se essa coluna deve ser classificada por padrão.
- PlaceholderTemplate: se especificado, as grades virtualizadas usam esse modelo para renderizar células cujos dados não tenham sido carregados.
- HeaderTemplate: um modelo opcional para a célula de cabeçalho desta coluna. Se não for especificado, o modelo de cabeçalho padrão inclui o Title, juntamente com os botões de opções e indicadores de classificação aplicáveis.
- Title: texto do título da coluna. O título será renderizado automaticamente se HeaderTemplate não for usado.
Por exemplo, adicione o seguinte componente para renderizar uma grade.
Para Blazor Web Apps, o componente QuickGrid deve adotar um modo de renderização interativo para habilitar recursos interativos, como paginação e classificação.
PromotionGrid.razor:
@page "/promotion-grid"
@using Microsoft.AspNetCore.Components.QuickGrid
<PageTitle>Promotion Grid</PageTitle>
<h1>Promotion Grid Example</h1>
<QuickGrid Items="people">
<PropertyColumn Property="@(p => p.PersonId)" Sortable="true" />
<PropertyColumn Property="@(p => p.Name)" Sortable="true" />
<PropertyColumn Property="@(p => p.PromotionDate)" Format="yyyy-MM-dd" Sortable="true" />
</QuickGrid>
@code {
private record Person(int PersonId, string Name, DateOnly PromotionDate);
private IQueryable<Person> people = new[]
{
new Person(10895, "Jean Martin", new DateOnly(1985, 3, 16)),
new Person(10944, "António Langa", new DateOnly(1991, 12, 1)),
new Person(11203, "Julie Smith", new DateOnly(1958, 10, 10)),
new Person(11205, "Nur Sari", new DateOnly(1922, 4, 27)),
new Person(11898, "Jose Hernandez", new DateOnly(2011, 5, 3)),
new Person(12130, "Kenji Sato", new DateOnly(2004, 1, 9)),
}.AsQueryable();
}
@page "/promotion-grid"
@using Microsoft.AspNetCore.Components.QuickGrid
<PageTitle>Promotion Grid</PageTitle>
<h1>Promotion Grid Example</h1>
<QuickGrid Items="people">
<PropertyColumn Property="@(p => p.PersonId)" Sortable="true" />
<PropertyColumn Property="@(p => p.Name)" Sortable="true" />
<PropertyColumn Property="@(p => p.PromotionDate)" Format="yyyy-MM-dd" Sortable="true" />
</QuickGrid>
@code {
private record Person(int PersonId, string Name, DateOnly PromotionDate);
private IQueryable<Person> people = new[]
{
new Person(10895, "Jean Martin", new DateOnly(1985, 3, 16)),
new Person(10944, "António Langa", new DateOnly(1991, 12, 1)),
new Person(11203, "Julie Smith", new DateOnly(1958, 10, 10)),
new Person(11205, "Nur Sari", new DateOnly(1922, 4, 27)),
new Person(11898, "Jose Hernandez", new DateOnly(2011, 5, 3)),
new Person(12130, "Kenji Sato", new DateOnly(2004, 1, 9)),
}.AsQueryable();
}
Acesse o componente em um navegador no caminho relativo /promotion-grid.
No momento, não há planos para estender QuickGrid com recursos que as grades comerciais completas tendem a oferecer, como linhas hierárquicas, colunas de arrastar para reordenar ou seleções de intervalo semelhantes ao Excel. Se você precisar de recursos avançados que não deseja desenvolver por conta própria, continue usando grades de terceiros.
Classificar por coluna
O componente QuickGrid pode classificar itens por colunas. Em Blazor Web Apps, a classificação requer que o componente adote um modo de renderização interativo.
Adicione Sortable="true" (Sortable) à marca PropertyColumn<TGridItem,TProp>:
<PropertyColumn Property="..." Sortable="true" />
No aplicativo em execução, classifique a coluna QuickGrid selecionando o título da coluna renderizada.
Itens de página com um componente Paginator
O componente QuickGrid pode paginar dados da fonte de dados. Em Blazor Web Apps, a paginação requer que o componente adote um modo de renderização interativo.
Adicione uma instância PaginationState ao bloco @code do componente. Defina o ItemsPerPage para o número de itens a serem exibidos por página. No exemplo a seguir, a instância é denominada pagination e são definidos dez itens por página:
PaginationState pagination = new PaginationState { ItemsPerPage = 10 };
Defina a propriedade QuickGrid do componente Pagination como pagination:
<QuickGrid Items="..." Pagination="pagination">
Para fornecer uma interface de paginação, adicione um componente Paginator acima ou abaixo do componente QuickGrid. Defina Paginator.State como pagination:
<Paginator State="pagination" />
No aplicativo em execução, navegue pelos itens usando um componente Paginator renderizado.
QuickGrid renderiza linhas vazias adicionais para preencher a página final dos dados quando usadas com um Paginator componente. No .NET 9 ou posterior, células de dados vazias (<td></td>) são adicionadas às linhas vazias. As linhas vazias destinam-se a facilitar a renderização do QuickGrid com altura de linha estável e estilo consistente em todas as páginas.
Aplicar estilos às linhas
Aplique estilos a linhas usando Isolamento CSS, que pode incluir estilização de linhas vazias para QuickGrid componentes para dados de página com um componentePaginator component.
Encapsular o componente QuickGrid em um elemento de bloco encapsulador, por exemplo, um <div>:
+ <div>
<QuickGrid ...>
...
</QuickGrid>
+ </div>
Aplique um estilo de linha com o ::deeppseudo-elemento. No exemplo a seguir, a altura da linha é definida como 2em, inclusive para linhas de dados vazias.
{COMPONENT}.razor.css:
::deep tr {
height: 2em;
}
Como alternativa, use a seguinte abordagem de estilo CSS:
- Exibir células de linha preenchidas com dados.
- Não exiba células de linhas vazias, evitando que as bordas das células de linhas vazias sejam exibidas de acordo com a estilização do Bootstrap.
{COMPONENT}.razor.css:
::deep tr:has(> td:not(:empty)) > td {
display: table-cell;
}
::deep td:empty {
display: none;
}
Para obter mais informações sobre como usar ::deeppseudo-elements com isolamento CSS, consulte ASP.NET Core Blazor isolamento CSS.
Atributos e estilos personalizados
QuickGrid também dá suporte à passagem de atributos personalizados e classes de estilo (Class) para o elemento de tabela renderizado:
<QuickGrid Items="..." custom-attribute="value" Class="custom-class">
Estilizar uma linha de tabela com base no item da linha
Aplique uma classe de folha de estilo a uma linha da grade com base no item da linha usando o novo parâmetro RowClass.
No exemplo a seguir:
- Um item de linha é representado pelo
Personregistro. OPersonregistro inclui umaFirstNamepropriedade. - O
GetRowCssClassmétodo aplica os estilos da classehighlight-rowa qualquer linha em que o nome da pessoa seja "Julie".
<QuickGrid ... RowClass="GetRowCssClass">
...
</QuickGrid>
@code {
private record Person(int PersonId, string FirstName, string LastName);
private string GetRowCssClass(Person person) =>
person.FirstName == "Julie" ? "highlight-row" : null;
}
Fechar opções de coluna QuickGrid
Feche a interface do usuário das opções de coluna QuickGrid com o método HideColumnOptionsAsync.
O exemplo a seguir fecha a interface do usuário das opções de coluna assim que o filtro de título é aplicado:
<QuickGrid @ref="movieGrid" Items="movies">
<PropertyColumn Property="@(m => m.Title)" Title="Title">
<ColumnOptions>
<input type="search" @bind="titleFilter" placeholder="Filter by title"
@bind:after="@(() => movieGrid.HideColumnOptionsAsync())" />
</ColumnOptions>
</PropertyColumn>
<PropertyColumn Property="@(m => m.Genre)" Title="Genre" />
<PropertyColumn Property="@(m => m.ReleaseYear)" Title="Release Year" />
</QuickGrid>
@code {
private QuickGrid<Movie>? movieGrid;
private string titleFilter = string.Empty;
private IQueryable<Movie> movies = new List<Movie> { ... }.AsQueryable();
private IQueryable<Movie> filteredMovies =>
movies.Where(m => m.Title!.Contains(titleFilter));
}
fonte de dados Entity Framework Core (EF Core)
Use o padrão de fábrica para resolver um contexto de banco de dados EF Core que fornece dados para um componente QuickGrid. Para obter mais informações sobre por que o padrão de fábrica é recomendado, consulte ASP.NET Core Blazor com Entity Framework Core (EF Core).
Uma fábrica de contexto de banco de dados (IDbContextFactory<TContext>) é injetada no componente com a diretiva @inject. A abordagem de fábrica requer o descarte do contexto do banco de dados, portanto, o componente implementa a interface IAsyncDisposable com a diretiva @implements. O provedor de itens para o componente QuickGrid é um DbSet<T> obtido do contexto do banco de dados criado (CreateDbContext) da fábrica de contexto do banco de dados injetado.
QuickGrid reconhece instâncias fornecidas por IQueryable EF e sabe como resolver consultas de forma assíncrona para obter eficiência.
Adicione uma referência de pacote para o Microsoft.AspNetCore.Components.QuickGrid.EntityFrameworkAdapter pacote NuGet.
Observação
Para obter diretrizes sobre como adicionar pacotes a aplicativos .NET, consulte os artigos em Instalar e gerenciar pacotes em Fluxo de trabalho de consumo de pacotes (documentação do NuGet). Confirme as versões corretas de pacote em NuGet.org.
Chame AddQuickGridEntityFrameworkAdapter na coleta de serviço no arquivo Program para registrar uma implementação de IAsyncQueryExecutor com reconhecimento de EF:
builder.Services.AddQuickGridEntityFrameworkAdapter();
O exemplo a seguir usa um ExampleTableDbSet<TEntity> (tabela) de um contexto de banco de dados AppDbContext (context) como fonte de dados para um componente QuickGrid:
@using Microsoft.AspNetCore.Components.QuickGrid
@using Microsoft.EntityFrameworkCore
@implements IAsyncDisposable
@inject IDbContextFactory<AppDbContext> DbFactory
...
<QuickGrid ... Items="context.ExampleTable" ...>
...
</QuickGrid>
@code {
private AppDbContext context = default!;
protected override void OnInitialized()
{
context = DbFactory.CreateDbContext();
}
public async ValueTask DisposeAsync() => await context.DisposeAsync();
}
No bloco de código (@code) do exemplo anterior:
- O campo
contextcontém o contexto do banco de dados, digitado como umAppDbContext. - O método de ciclo de vida
OnInitializedatribui um novo contexto de banco de dados (CreateDbContext) ao campocontextda fábrica injetada (DbFactory). - O método assíncrono
DisposeAsyncdescarta o contexto do banco de dados quando o componente é descartado.
Você também pode usar qualquer operador LINQ compatível com EF para filtrar os dados antes de passá-los para o parâmetro Items.
O exemplo a seguir filtra filmes por um título de filme inserido em uma caixa de pesquisa. O contexto do banco de dados é BlazorWebAppMoviesContext e o modelo é Movie. A propriedade Title do filme é usada para a operação de filtro.
@using Microsoft.AspNetCore.Components.QuickGrid
@using Microsoft.EntityFrameworkCore
@implements IAsyncDisposable
@inject IDbContextFactory<BlazorWebAppMoviesContext> DbFactory
...
<p>
<input type="search" @bind="titleFilter" @bind:event="oninput" />
</p>
<QuickGrid ... Items="FilteredMovies" ...>
...
</QuickGrid>
@code {
private string titleFilter = string.Empty;
private BlazorWebAppMoviesContext context = default!;
protected override void OnInitialized()
{
context = DbFactory.CreateDbContext();
}
private IQueryable<Movie> FilteredMovies =>
context.Movie.Where(m => m.Title!.Contains(titleFilter));
public async ValueTask DisposeAsync() => await context.DisposeAsync();
}
Para obter um exemplo de trabalho, consulte os seguintes recursos:
- Tutorial Criar um Blazor aplicativo de banco de dados de filmes
-
Blazor Aplicativo de exemplo de base de dados de filmes: selecione a pasta da versão mais recente no repositório. A pasta de exemplo do projeto do tutorial é chamada
BlazorWebAppMovies.
Suporte ao nome de exibição
Um título de coluna pode ser atribuído usando ColumnBase<TGridItem>.Title na etiqueta de PropertyColumn<TGridItem,TProp>. No exemplo de um filme a seguir, a coluna recebe o nome "Release Date" para os dados de data de lançamento do filme.
<PropertyColumn Property="movie => movie.ReleaseDate" Title="Release Date" />
No entanto, gerenciar títulos de coluna (nomes) a partir de propriedades de modelo de dados vinculadas geralmente é uma opção melhor para a manutenção de um aplicativo. Um modelo pode controlar o nome de exibição de uma propriedade com o [Display] atributo. No seguinte exemplo, o modelo especifica um nome de exibição de data de lançamento do filme de "Release Date" para a propriedade ReleaseDate dele:
[Display(Name = "Release Date")]
public DateTime ReleaseDate { get; set; }
Para habilitar o componente QuickGrid a usar a propriedade DisplayAttribute.Name, subclasse PropertyColumn<TGridItem,TProp>, seja no componente ou em uma classe separada. Chame o método GetName para retornar o valor DisplayAttribute.Name localizado se um atributo DisplayName não localizado ([DisplayName]) não contiver o valor:
public class DisplayNameColumn<TGridItem, TProp> : PropertyColumn<TGridItem, TProp>
{
protected override void OnParametersSet()
{
if (Title is null && Property.Body is MemberExpression memberExpression)
{
var memberInfo = memberExpression.Member;
Title =
memberInfo.GetCustomAttribute<DisplayNameAttribute>().DisplayName ??
memberInfo.GetCustomAttribute<DisplayAttribute>().GetName() ??
memberInfo.Name;
}
base.OnParametersSet();
}
}
Use a subclasse no componente QuickGrid. No exemplo a seguir, a DisplayNameColumn anterior é usada. O nome "Release Date" é fornecido pelo atributo [Display] no modelo, portanto, não é necessário especificar um Title:
<DisplayNameColumn Property="movie => movie.ReleaseDate" />
O atributo [DisplayName] também é compatível:
[DisplayName("Release Date")]
public DateTime ReleaseDate { get; set; }
No entanto, o atributo [Display] é recomendado porque disponibiliza propriedades adicionais. Por exemplo, o atributo [Display] oferece a capacidade de atribuir um tipo de recurso para localização.
Dados remotos
Em aplicativos Blazor WebAssembly, buscar dados de uma API Web baseada em JSON em um servidor é um requisito comum. Para buscar apenas os dados necessários para a página/visor atual de dados e aplicar regras de classificação ou filtragem no servidor, use o parâmetro ItemsProvider.
ItemsProvider também poderá ser usado em um aplicativo Blazor do lado do servidor se o aplicativo for necessário para consultar um ponto de extremidade externo ou em outros casos em que os requisitos não são cobertos por um IQueryable.
Forneça um retorno de chamada correspondente ao tipo delegado GridItemsProvider<TGridItem>, em que TGridItemé o tipo dos dados exibidos na grade. O retorno de chamada recebe um parâmetro de tipo GridItemsProviderRequest<TGridItem>, que especifica o índice inicial, a contagem máxima de linhas e a ordem de classificação dos dados a serem retornados. Além de retornar os itens correspondentes, uma contagem total de itens (totalItemCount) também é necessária para que a paginação e a virtualização funcionem corretamente.
O exemplo a seguir obtém dados do banco de dados público OpenFDA Food Enforcement.
O GridItemsProvider<TGridItem> converte GridItemsProviderRequest<TGridItem> em uma consulta no banco de dados OpenFDA. Os parâmetros de consulta são convertidos no formato de URL específico compatível com a API JSON externa. Só é possível executar a classificação e a filtragem por meio da classificação e filtragem compatíveis com a API externa. O endpoint OpenFDA não oferece suporte à classificação, portanto, nenhuma coluna está marcada como classificável. No entanto, ele dá suporte a ignorar registros (parâmetro skip) e limitar o retorno de registros (parâmetro limit), de modo que o componente possa habilitar a virtualização e rolar rapidamente por dezenas de milhares de registros.
FoodRecalls.razor:
@page "/food-recalls"
@inject HttpClient Http
@inject NavigationManager Navigation
<PageTitle>Food Recalls</PageTitle>
<h1>OpenFDA Food Recalls</h1>
<div class="grid" tabindex="-1">
<QuickGrid ItemsProvider="@foodRecallProvider" Virtualize="true">
<PropertyColumn Title="ID" Property="@(c => c.Event_Id)" />
<PropertyColumn Property="@(c => c.State)" />
<PropertyColumn Property="@(c => c.City)" />
<PropertyColumn Title="Company" Property="@(c => c.Recalling_Firm)" />
<PropertyColumn Property="@(c => c.Status)" />
</QuickGrid>
</div>
<p>Total: <strong>@numResults results found</strong></p>
@code {
private GridItemsProvider<FoodRecall>? foodRecallProvider;
private int numResults;
protected override async Task OnInitializedAsync()
{
foodRecallProvider = async req =>
{
var url = Navigation.GetUriWithQueryParameters(
"https://api.fda.gov/food/enforcement.json",
new Dictionary<string, object?>
{
{ "skip", req.StartIndex },
{ "limit", req.Count },
});
using var response = await Http.GetFromJsonAsync<FoodRecallQueryResult>(
url, req.CancellationToken);
return GridItemsProviderResult.From(
items: response!.Results,
totalItemCount: response!.Meta.Results.Total);
};
numResults = (await Http.GetFromJsonAsync<FoodRecallQueryResult>(
"https://api.fda.gov/food/enforcement.json"))!.Meta.Results.Total;
}
}
Para obter mais informações sobre como chamar APIs Web, consulte Call a Web API from an ASP.NET Core Blazor app.
QuickGrid scaffolder
O QuickGrid scaffolder estrutura Razor componentes com QuickGrid para exibir dados de um banco de dados.
O scaffolder gera páginas CRUD (Criar, Ler, Atualizar e Excluir) básicas com base em um modelo de dados Entity Framework Core. Você pode scaffoldar páginas individuais ou todas as páginas de CRUD. Selecione a classe de modelo e o DbContext, opcionalmente criando um DbContext, se necessário.
Os componentes Razor de scaffold são adicionados ao projeto em uma pasta gerada com o nome da classe do modelo. O componente Index gerado usa um componente QuickGrid para exibir os dados. Personalize os componentes gerados conforme necessário e habilite a interatividade para aproveitar recursos interativos, como paginação, classificação e filtragem.
Os componentes produzidos pelo scaffolder requerem renderização do lado do servidor (SSR), portanto, não são suportados quando executados no WebAssembly.
Clique com o botão direito do mouse na pasta Components/Pages e selecione Adicionar>Novo Item Estruturado.
Com a caixa de diálogo Adicionar Novo Item em Scaffolding aberta em Instalado>Comum>Blazor>Razor Componente, selecione Razor Componentes que usam Entity Framework (CRUD). Selecione o botão Adicionar.
CRUD é um acrônimo para Criar, Ler, Atualizar e Excluir. O scaffolder produz componentes de criação, edição, exclusão, detalhes e índice para o aplicativo.
Preencha o campo Adicionar Razor Componentes usando o Entity Framework (CRUD):
- A lista suspensa Modelo inclui outros modelos para criar especificamente componentes de criação, edição, exclusão, detalhes e listagem. Essa lista suspensa é útil quando você precisa criar apenas um tipo específico de componente em scaffolding para uma classe de modelo. Deixe a lista suspensa Modelo definida como CRUD para criar um conjunto completo de componentes em scaffolding.
- Na lista suspensa Classe do modelo, selecione a classe do modelo. Uma pasta é criada para os componentes gerados a partir do nome do modelo (se a classe do modelo for nomeada
Movie, a pasta será automaticamente nomeadaMoviePages). - Para classe DbContext, siga uma das seguintes abordagens:
- Selecione uma classe de DbContext existente que você sabe que tem um registro de provedor de fábrica (AddDbContextFactory).
- Selecione o botão + (sinal de adição) e use a caixa de diálogo modal Adicionar Contexto de Dados para especificar um novo nome de classe DbContext, que registra a classe com um provedor de fábrica ao invés de utilizar diretamente o tipo de contexto como um registro de serviço.
- Depois do fechamento da caixa de diálogo do modelo, a lista suspensa Provedor de banco de dados será padronizada para SQL Server. Você pode selecionar o provedor apropriado para o banco de dados que estiver usando. As opções incluem SQL Server, SQLite, PostgreSQL e Azure Cosmos DB.
- Selecione Adicionar.
Para obter um exemplo de uso do QuickGrid scaffolder, consulte Criar um Blazor aplicativo de banco de dados de filmes (visão geral).
Várias consultas EF Core simultâneas disparam System.InvalidOperationException
Várias consultas EF Core simultâneas podem provocar o seguinte System.InvalidOperationException:
System.InvalidOperationException: uma segunda operação foi iniciada nesta instância de contexto antes da conclusão de uma operação anterior. Isso geralmente é causado por threads diferentes simultaneamente usando a mesma instância de DbContext. Para obter mais informações sobre como evitar problemas de threading com dbContext, consulte https://go.microsoft.com/fwlink/?linkid=2097913.
Esse cenário está programado para ser melhorado em uma futura versão do ASP.NET Core. Para obter mais informações, consulte [Blazor] Aprimorar a experiência com QuickGrid e EF Core (dotnet/aspnetcore nº 58716).
Enquanto isso, você pode resolver o problema usando um ItemsProvider com um token de cancelamento. O token de cancelamento impede consultas simultâneas cancelando a solicitação anterior quando uma nova solicitação é emitida.
Considere o exemplo a seguir, que se baseia no componente de banco de dados Index de filme para o tutorial Criar um Blazor aplicativo de banco de dados de filme (Visão geral ). A versão mais simples estruturada no aplicativo pode ser vista no aplicativo de exemplo do artigo. O componente Index que foi estruturado no aplicativo é substituído pelo componente a seguir.
Components/Pages/MoviePages/Index.razor:
@page "/movies"
@rendermode InteractiveServer
@using Microsoft.EntityFrameworkCore
@using Microsoft.AspNetCore.Components.QuickGrid
@using BlazorWebAppMovies.Models
@using BlazorWebAppMovies.Data
@inject IDbContextFactory<BlazorWebAppMovies.Data.BlazorWebAppMoviesContext> DbFactory
<PageTitle>Index</PageTitle>
<h1>Index</h1>
<div>
<input type="search" @bind="titleFilter" @bind:event="oninput" />
</div>
<p>
<a href="movies/create">Create New</a>
</p>
<div>
<QuickGrid Class="table" TGridItem="Movie" ItemsProvider="GetMovies"
ItemKey="(x => x.Id)" Pagination="pagination">
<PropertyColumn Property="movie => movie.Title" Sortable="true" />
<PropertyColumn Property="movie => movie.ReleaseDate" Title="Release Date" />
<PropertyColumn Property="movie => movie.Genre" />
<PropertyColumn Property="movie => movie.Price" />
<PropertyColumn Property="movie => movie.Rating" />
<TemplateColumn Context="movie">
<a href="@($"movies/edit?id={movie.Id}")">Edit</a> |
<a href="@($"movies/details?id={movie.Id}")">Details</a> |
<a href="@($"movies/delete?id={movie.Id}")">Delete</a>
</TemplateColumn>
</QuickGrid>
</div>
<Paginator State="pagination" />
@code {
private BlazorWebAppMoviesContext context = default!;
private PaginationState pagination = new PaginationState { ItemsPerPage = 5 };
private string titleFilter = string.Empty;
public async ValueTask<GridItemsProviderResult<Movie>> GetMovies(GridItemsProviderRequest<Movie> request)
{
using var context = DbFactory.CreateDbContext();
var totalCount = await context.Movie.CountAsync(request.CancellationToken);
IQueryable<Movie> query = context.Movie.OrderBy(x => x.Id);
query = request.ApplySorting(query).Skip(request.StartIndex);
if (request.Count.HasValue)
{
query = query.Take(request.Count.Value);
}
var items = await query.ToArrayAsync(request.CancellationToken);
var result = new GridItemsProviderResult<Movie>
{
Items = items,
TotalItemCount = totalCount
};
return result;
}
}