компонент ASP.NET Core BlazorQuickGrid

Компонент QuickGrid — это Razor компонент для быстрого и эффективного отображения данных в табличной форме. QuickGrid предоставляет простой и удобный компонент сетки данных для распространенных сценариев отрисовки сетки и служит эталонной архитектурой и базовым показателем производительности для создания компонентов сетки данных. QuickGrid высокооптимизируется и использует расширенные методы для достижения оптимальной производительности отрисовки.

Пакет

Добавьте ссылку на пакет.Microsoft.AspNetCore.Components.QuickGrid

Примечание.

Рекомендации по добавлению пакетов в приложения .NET см. в разделе Способы установки пакетов NuGet в статье Рабочий процесс использования пакета (документация по NuGet). Проверьте правильность версий пакета на сайте NuGet.org.

Пример приложения

Сведения о различных QuickGrid демонстрациях см. в разделе QuickGrid для Blazor примера приложения. Демонстрационный сайт размещен на страницах GitHub. Сайт загружается быстро благодаря статической предварительной подготовке с помощью проекта GitHub, поддерживаемого BlazorWasmPrerendering.Build сообществом.

QuickGrid реализация

Чтобы реализовать QuickGrid компонент, выполните следующие действия.

  • Укажите теги для компонента в Razor разметке QuickGrid (<QuickGrid>...</QuickGrid>).
  • Назовите запрашиваемый источник данных для сетки. Используйте любой из следующих источников данных:
    • Items: значение IQueryable<TGridItem>NULL, где TGridItem тип данных, представленных каждой строкой в сетке.
    • ItemsProvider: обратный вызов, предоставляющий данные для сетки.
  • Class: необязательное имя класса CSS. При условии имя класса включается в class атрибут отрисоченной таблицы.
  • Theme: имя темы (значение по умолчанию: default). Это влияет на то, какие правила стилизации соответствуют таблице.
  • Virtualize: если значение true, сетка отрисовывается с помощью виртуализации. Обычно это используется в сочетании с прокруткой и приводит к тому, что сетка извлекает и отрисовывает только данные вокруг текущего окна просмотра прокрутки. Это может значительно повысить производительность при прокрутке больших наборов данных. Если используется Virtualize, необходимо указать значение ItemSize и убедиться, что каждая строка отображается с постоянной высотой. Как правило, предпочтительнее не использовать Virtualize , если объем отрисовки данных мал или используется разбиение на страницы.
  • ItemSize: применимо только при использовании Virtualize. ItemSize определяет ожидаемую высоту в пикселях для каждой строки, позволяя механизму виртуализации получить правильное количество элементов для сопоставления размера дисплея и обеспечить точную прокрутку.
  • ItemKey: при необходимости определяет значение для @key каждой отрисованной строки. Как правило, это используется для указания уникального идентификатора, например значения первичного ключа для каждого элемента данных. Это позволяет сетке сохранять связь между элементами строк и элементами данных на основе их уникальных идентификаторов, даже если TGridItem экземпляры заменяются новыми копиями (например, после нового запроса к базовому хранилищу данных). Если этот параметр не задан, @key это TGridItem экземпляр.
  • OverscanCount: определяет количество дополнительных элементов для отрисовки до и после видимого региона, чтобы уменьшить частоту отрисовки во время прокрутки. Хотя более высокие значения могут улучшить плавность прокрутки, отрисовка дополнительных элементов вне экрана, более высокое значение также может привести к увеличению времени начальной загрузки. Рекомендуется найти баланс на основе размера набора данных и требований к пользовательскому интерфейсу. Значение по умолчанию равно 3. Доступно только при использовании Virtualize.
  • Pagination: при необходимости связывает этот TGridItem экземпляр с PaginationState моделью, что приводит к выборке и отрисовке только текущей страницы данных. Обычно это используется в сочетании с компонентом Paginator или другой логикой пользовательского интерфейса, которая отображает и обновляет предоставленный PaginationState экземпляр.
  • В дочернем содержимом QuickGrid (RenderFragment) укажите PropertyColumn<TGridItem,TProp>столбцы, ячейки которых отображают TGridItem значения:
    • Property: определяет значение, отображаемое в ячейках этого столбца.
    • Format: необязательно указывает строку формата для значения. Использование Format требует TProp , чтобы тип был реализован IFormattable.
    • Sortable: указывает, должны ли данные сортироваться по этому столбцу. Значение по умолчанию может отличаться в зависимости от типа столбца. Например, сортируется, TemplateColumn<TGridItem> если указан какой-либо SortBy параметр.
    • InitialSortDirection: указывает направление сортировки, если IsDefaultSortColumn есть true.
    • IsDefaultSortColumn: указывает, следует ли отсортировать этот столбец по умолчанию.
    • PlaceholderTemplate: при указании виртуализированные сетки используют этот шаблон для отрисовки ячеек, данные которых не были загружены.
    • HeaderTemplate: необязательный шаблон для ячейки заголовка этого столбца. Если он не указан, шаблон заголовка по умолчанию включает в себя Titleвсе применимые индикаторы сортировки и кнопки параметров.
    • Title: заголовок текста для столбца. Заголовок отображается автоматически, если HeaderTemplate он не используется.
  • Укажите теги для компонента в Razor разметке QuickGrid (<QuickGrid>...</QuickGrid>).
  • Назовите запрашиваемый источник данных для сетки. Используйте любой из следующих источников данных:
    • Items: значение IQueryable<TGridItem>NULL, где TGridItem тип данных, представленных каждой строкой в сетке.
    • ItemsProvider: обратный вызов, предоставляющий данные для сетки.
  • Class: необязательное имя класса CSS. При условии имя класса включается в class атрибут отрисоченной таблицы.
  • Theme: имя темы (значение по умолчанию: default). Это влияет на то, какие правила стилизации соответствуют таблице.
  • Virtualize: если значение true, сетка отрисовывается с помощью виртуализации. Обычно это используется в сочетании с прокруткой и приводит к тому, что сетка извлекает и отрисовывает только данные вокруг текущего окна просмотра прокрутки. Это может значительно повысить производительность при прокрутке больших наборов данных. Если используется Virtualize, необходимо указать значение ItemSize и убедиться, что каждая строка отображается с постоянной высотой. Как правило, предпочтительнее не использовать Virtualize , если объем отрисовки данных мал или используется разбиение на страницы.
  • ItemSize: применимо только при использовании Virtualize. ItemSize определяет ожидаемую высоту в пикселях для каждой строки, позволяя механизму виртуализации получить правильное количество элементов для сопоставления размера дисплея и обеспечить точную прокрутку.
  • ItemKey: при необходимости определяет значение для @key каждой отрисованной строки. Как правило, это используется для указания уникального идентификатора, например значения первичного ключа для каждого элемента данных. Это позволяет сетке сохранять связь между элементами строк и элементами данных на основе их уникальных идентификаторов, даже если TGridItem экземпляры заменяются новыми копиями (например, после нового запроса к базовому хранилищу данных). Если этот параметр не задан, @key это TGridItem экземпляр.
  • Pagination: при необходимости связывает этот TGridItem экземпляр с PaginationState моделью, что приводит к выборке и отрисовке только текущей страницы данных. Обычно это используется в сочетании с компонентом Paginator или другой логикой пользовательского интерфейса, которая отображает и обновляет предоставленный PaginationState экземпляр.
  • В дочернем содержимом QuickGrid (RenderFragment) укажите PropertyColumn<TGridItem,TProp>столбцы, ячейки которых отображают TGridItem значения:
    • Property: определяет значение, отображаемое в ячейках этого столбца.
    • Format: необязательно указывает строку формата для значения. Использование Format требует TProp , чтобы тип был реализован IFormattable.
    • Sortable: указывает, должны ли данные сортироваться по этому столбцу. Значение по умолчанию может отличаться в зависимости от типа столбца. Например, сортируется, TemplateColumn<TGridItem> если указан какой-либо SortBy параметр.
    • InitialSortDirection: указывает направление сортировки, если IsDefaultSortColumn есть true.
    • IsDefaultSortColumn: указывает, следует ли отсортировать этот столбец по умолчанию.
    • PlaceholderTemplate: при указании виртуализированные сетки используют этот шаблон для отрисовки ячеек, данные которых не были загружены.
    • HeaderTemplate: необязательный шаблон для ячейки заголовка этого столбца. Если он не указан, шаблон заголовка по умолчанию включает в себя Titleвсе применимые индикаторы сортировки и кнопки параметров.
    • Title: заголовок текста для столбца. Заголовок отображается автоматически, если HeaderTemplate он не используется.

Например, добавьте следующий компонент для отрисовки сетки.

Для Blazor Web Apps QuickGrid компонент должен использовать интерактивный режим отрисовки, чтобы включить интерактивные функции, такие как разбиение по страницам и сортировка.

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();
}

Доступ к компоненту в браузере по относительному пути /promotion-grid.

Существуют не текущие планы расширения QuickGrid с функциями, которые полнофункционально предлагают коммерческие сетки, например иерархические строки, перетаскивание к переупорядочению столбцов или выборы диапазона, например excel. Если вам нужны расширенные функции, которые вы не хотите разрабатывать самостоятельно, продолжайте использовать сторонние сетки.

Сортировка по столбцу

Компонент QuickGrid может сортировать элементы по столбцам. Для Blazor Web Appсортировки требуется, чтобы компонент принял интерактивный режим отрисовки.

Добавьте Sortable="true" (Sortable) в PropertyColumn<TGridItem,TProp> тег:

<PropertyColumn Property="..." Sortable="true" />

В работающем приложении отсортируйте QuickGrid столбец, выбрав отрисованное название столбца.

Элементы страницы с компонентом Paginator

Компонент QuickGrid может страницы данных из источника данных. Для Blazor Web Appразбиения на страницы требуется, чтобы компонент принял интерактивный режим отрисовки.

PaginationState Добавьте экземпляр в блок компонента@code. ItemsPerPage Задайте для каждого страницы число элементов. В следующем примере экземпляр называется pagination, а для каждой страницы задано десять элементов:

PaginationState pagination = new PaginationState { ItemsPerPage = 10 };

QuickGrid Задайте для свойства paginationкомпонента Pagination значение :

<QuickGrid Items="..." Pagination="pagination">

Чтобы предоставить пользовательский интерфейс для разбиения на страницы, добавьте Paginator компонент выше или ниже QuickGrid компонента. Задайте для Paginator.State pagination:

<Paginator State="pagination" />

В работающем приложении страницу элементов с помощью отрисованного Paginator компонента.

Настраиваемые атрибуты и стили

QuickGrid также поддерживает передачу пользовательских атрибутов и классов стилей (Class) в отрисованный элемент таблицы:

<QuickGrid Items="..." custom-attribute="value" Class="custom-class">

Источник данных Entity Framework Core (EF Core)

Используйте шаблон фабрики для разрешения контекста EF Core базы данных, предоставляющего данные компоненту QuickGrid . Дополнительные сведения о том, почему шаблон фабрики рекомендуется, см. в разделе ASP.NET Core Blazor с Entity Framework Core (EF Core).

Фабрика контекста базы данных (IDbContextFactory<TContext>) внедряется в компонент с директивой @inject . Подход фабрики требует удаления контекста базы данных, поэтому компонент реализует IAsyncDisposable интерфейс с директивой @implements . Поставщик элементов для QuickGrid компонента — это DbSet<T> полученный из созданного контекста базы данных (CreateDbContext) в внедренной фабрике контекста базы данных.

QuickGrid распознает экземпляры, предоставляемые IQueryable EF, и знает, как асинхронно разрешать запросы для повышения эффективности.

Добавьте ссылку на Microsoft.AspNetCore.Components.QuickGrid.EntityFrameworkAdapter пакет NuGet.

Примечание.

Рекомендации по добавлению пакетов в приложения .NET см. в разделе Способы установки пакетов NuGet в статье Рабочий процесс использования пакета (документация по NuGet). Проверьте правильность версий пакета на сайте NuGet.org.

Вызовите AddQuickGridEntityFrameworkAdapter коллекцию служб в Program файле, чтобы зарегистрировать реализацию с поддержкой IAsyncQueryExecutor EF:

builder.Services.AddQuickGridEntityFrameworkAdapter();

В следующем примере используется ExampleTable DbSet<TEntity> (таблица) из контекста AppDbContext базы данных (context) в качестве источника данных для 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();
}

В блоке кода (@code) предыдущего примера:

  • Поле context содержит контекст базы данных, типизированный как .AppDbContext
  • Метод OnInitialized жизненного цикла назначает новый контекст базы данных (CreateDbContext) context полю из внедренной фабрики (DbFactory).
  • Асинхронный DisposeAsync метод удаляет контекст базы данных при удалении компонента.

Вы также можете использовать любой оператор LINQ, поддерживаемый EF, чтобы отфильтровать данные перед передачей Items в параметр.

В следующем примере фильмы фильтруется по названию фильма, введенном в поле поиска. Контекст базы данных — BlazorWebAppMoviesContextи модель Movie. Свойство фильма Title используется для операции фильтра.

@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();
}

Поддержка отображаемого имени

Название столбца можно назначить с помощью ColumnBase<TGridItem>.Title тега PropertyColumn<TGridItem,TProp>. В следующем примере фильма столбец получает имя "Release Date" для данных даты выпуска фильма столбца:

<PropertyColumn Property="movie => movie.ReleaseDate" Title="Release Date" />

Однако управление заголовками столбцов (именами) из свойств привязанной модели обычно лучше подходит для обслуживания приложения. Модель может контролировать отображаемое имя свойства с помощью атрибута[Display]. В следующем примере модель указывает отображаемое имя даты выпуска фильма "Release Date" для его ReleaseDate свойства:

[Display(Name = "Release Date")]
public DateTime ReleaseDate { get; set; }

Чтобы включить QuickGrid компонент для использования подкласса DisplayAttribute.NamePropertyColumn<TGridItem,TProp> , в компоненте или в отдельном классе:

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>().Name ??
                memberInfo.Name;
        }

        base.OnParametersSet();
    }
}

Используйте подкласс в компоненте QuickGrid . В следующем примере используется предыдущий DisplayNameColumn . Имя "Release Date" предоставляется атрибутом [Display] в модели, поэтому не нужно указывать:Title

<DisplayNameColumn Property="movie => movie.ReleaseDate" />

Атрибут [DisplayName] также поддерживается:

[DisplayName("Release Date")]
public DateTime ReleaseDate { get; set; }

Однако этот атрибут рекомендуется, [Display] так как он предоставляет дополнительные свойства. Например, [Display] атрибут предлагает возможность назначать тип ресурса для локализации.

Удаленные данные

В Blazor WebAssembly приложениях получение данных из веб-API на основе JSON на сервере является общим требованием. Чтобы получить только данные, необходимые для текущей страницы или представления данных, и применить правила сортировки или фильтрации на сервере, используйте ItemsProvider этот параметр.

ItemsProvider также можно использовать в серверном Blazor приложении, если приложению требуется запрашивать внешнюю конечную точку или в других случаях, когда требования не охватываются IQueryable.

Укажите обратный вызов, соответствующий типу GridItemsProvider<TGridItem> делегата, где TGridItem тип данных, отображаемых в сетке. Обратный вызов присваивается параметру типа GridItemsProviderRequest<TGridItem>, который задает начальный индекс, максимальное число строк и порядок сортировки возвращаемых данных. Помимо возврата соответствующих элементов, общее количество элементов (totalItemCount) также требуется для правильной работы по страницам и виртуализации.

Следующий пример получает данные из общедоступной базы данных OpenFDA Food Enforcement.

Объект GridItemsProvider<TGridItem> преобразует GridItemsProviderRequest<TGridItem> запрос в базу данных OpenFDA. Параметры запроса превратятся в определенный формат URL-адреса, поддерживаемый внешним API JSON. Выполнять сортировку и фильтрацию можно только через сортировку и фильтрацию, поддерживаемую внешним API. Конечная точка OpenFDA не поддерживает сортировку, поэтому ни один из столбцов не помечен как сортируемый. Однако она поддерживает пропуск записей (параметр) и ограничение возврата записей (skiplimitпараметра), поэтому компонент может включить виртуализацию и быстро прокручивать десятки тысяч записей.

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 },
            });

            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;
    }
}

Дополнительные сведения о вызове веб-API см. в статье "Вызов веб-API" из приложения ASP.NET CoreBlazor.

QuickGrid шаблон

Компоненты QuickGrid шаблонов Razor QuickGrid для отображения данных из базы данных.

Шаблон создает базовые страницы создания, чтения, обновления и удаления (CRUD) на основе модели данных Entity Framework Core. Вы можете сформировать отдельные страницы или все страницы CRUD. Вы выбираете класс модели и DbContextпри необходимости создаете новый DbContext объект.

Компоненты шаблонов Razor добавляются в проект в созданной папке с именем класса модели. Index Созданный компонент использует QuickGrid компонент для отображения данных. Настройте созданные компоненты по мере необходимости и включите интерактивность, чтобы воспользоваться интерактивными функциями, такими как разбиение по страницам, сортировка и фильтрация.

Компоненты, созданные шаблоном, требуют отрисовки на стороне сервера (SSR), поэтому они не поддерживаются при выполнении в WebAssembly.

Щелкните правой кнопкой мыши папку Components/Pages и выберите "Добавить>новый шаблонный элемент".

При открытии диалогового окна "Добавление нового шаблона" для установленного>общего>>BlazorRazor компонента выберите Razor компоненты с помощью Entity Framework (CRUD). Нажмите кнопку Добавить.

CRUD — это акроним для создания, чтения, обновления и удаления. Шаблон создает, редактирует, удаляет, детали и компоненты индекса для приложения.

Выполните диалоговое окно добавления Razor компонентов с помощью Entity Framework (CRUD):

  • Раскрывающийся список шаблонов включает другие шаблоны для создания, редактирования, удаления, удаления, сведений и компонентов списка. Этот раскрывающийся список пригодится, если необходимо создать определенный тип компонента, сформированный в класс модели. Оставьте раскрывающийся список шаблонов для CRUD, чтобы создать полный набор компонентов.
  • В раскрывающемся списке класса Model выберите класс модели. Папка создается для созданных компонентов из имени модели (если класс модели называется Movie, папка автоматически называется MoviePages).
  • Для класса DbContext выберите существующий контекст базы данных или + нажмите кнопку (плюс знак) и диалоговое окно "Добавить контекст данных", чтобы добавить новый контекст базы данных.
  • После закрытия диалогового окна модели раскрывающийся список поставщика базы данных по умолчанию используется для SQL Server. Вы можете выбрать подходящий поставщик для используемой базы данных. К ним относятся SQL Server, SQLite, PostgreSQL и Azure Cosmos DB.
  • Выберите Добавить.