| name | abp-blazor |
| description | ABP Blazor UI patterns - AbpComponentBase, AbpCrudPageBase, DataGrid, IMenuContributor, Message/Notify, Validations, JavaScript interop. Use when building or reviewing Blazor Server or WebAssembly UI components in ABP projects. |
ABP Blazor UI
Docs: https://abp.io/docs/latest/framework/ui/blazor/overall
Component Base Classes
Basic Component
@inherits AbpComponentBase
<h1>@L["Books"]</h1>
CRUD Page
@page "/books"
@inherits AbpCrudPageBase<IBookAppService, BookDto, Guid, PagedAndSortedResultRequestDto, CreateUpdateBookDto>
<Card>
<CardHeader>
<Row>
<Column>
<h2>@L["Books"]</h2>
</Column>
<Column TextAlignment="TextAlignment.End">
@if (HasCreatePermission)
{
<Button Color="Color.Primary" Clicked="OpenCreateModalAsync">
@L["NewBook"]
</Button>
}
</Column>
</Row>
</CardHeader>
<CardBody>
<DataGrid TItem="BookDto"
Data="Entities"
ReadData="OnDataGridReadAsync"
TotalItems="TotalCount"
ShowPager="true"
PageSize="PageSize">
<DataGridColumns>
<DataGridColumn Field="@nameof(BookDto.Name)" Caption="@L["Name"]" />
<DataGridColumn Field="@nameof(BookDto.Price)" Caption="@L["Price"]" />
<DataGridEntityActionsColumn TItem="BookDto">
<DisplayTemplate>
<EntityActions TItem="BookDto">
<EntityAction TItem="BookDto"
Text="@L["Edit"]"
Visible="HasUpdatePermission"
Clicked="() => OpenEditModalAsync(context)" />
<EntityAction TItem="BookDto"
Text="@L["Delete"]"
Visible="HasDeletePermission"
Clicked="() => DeleteEntityAsync(context)"
ConfirmationMessage="() => GetDeleteConfirmationMessage(context)" />
</EntityActions>
</DisplayTemplate>
</DataGridEntityActionsColumn>
</DataGridColumns>
</DataGrid>
</CardBody>
</Card>
Localization
@* Using L property from base class *@
<h1>@L["PageTitle"]</h1>
@* With parameters *@
<p>@L["WelcomeMessage", CurrentUser.UserName]</p>
Authorization
@* Check permission before rendering *@
@if (await AuthorizationService.IsGrantedAsync("MyPermission"))
{
<Button>Admin Action</Button>
}
@* Using policy-based authorization *@
<AuthorizeView Policy="MyPolicy">
<Authorized>
<p>You have access!</p>
</Authorized>
</AuthorizeView>
Navigation & Menu
Configure in *MenuContributor.cs:
public class MyMenuContributor : IMenuContributor
{
public async Task ConfigureMenuAsync(MenuConfigurationContext context)
{
if (context.Menu.Name == StandardMenus.Main)
{
var bookMenu = new ApplicationMenuItem(
"Books",
l["Menu:Books"],
"/books",
icon: "fa fa-book"
);
if (await context.IsGrantedAsync(MyPermissions.Books.Default))
{
context.Menu.AddItem(bookMenu);
}
}
}
}
Notifications & Messages
await Message.Success(L["BookCreatedSuccessfully"]);
if (await Message.Confirm(L["AreYouSure"]))
{
}
await Notify.Success(L["OperationCompleted"]);
Forms & Validation
<Form @ref="CreateForm">
<Validations @ref="CreateValidationsRef" Model="@NewEntity" ValidateOnLoad="false">
<Validation MessageLocalizer="@LH.Localize">
<Field>
<FieldLabel>@L["Name"]</FieldLabel>
<TextEdit @bind-Text="@NewEntity.Name">
<Feedback>
<ValidationError />
</Feedback>
</TextEdit>
</Field>
</Validation>
</Validations>
</Form>
JavaScript Interop
@inject IJSRuntime JsRuntime
@code {
private async Task CallJavaScript()
{
await JsRuntime.InvokeVoidAsync("myFunction", arg1, arg2);
var result = await JsRuntime.InvokeAsync<string>("myFunctionWithReturn");
}
}
State Management
@inject IBookAppService BookAppService
@code {
private List<BookDto> Books { get; set; }
protected override async Task OnInitializedAsync()
{
var result = await BookAppService.GetListAsync(new PagedAndSortedResultRequestDto());
Books = result.Items.ToList();
}
}
Code-Behind Pattern
Books.razor:
@page "/books"
@inherits BooksBase
Books.razor.cs:
public partial class Books : BooksBase
{
}
BooksBase.cs:
public abstract class BooksBase : AbpComponentBase
{
[Inject]
protected IBookAppService BookAppService { get; set; }
}