Blazor component patterns for interactive web UIs.
Blazor component patterns for interactive web UIs.
[Parameter] for one-way, EventCallback for two-way binding.EditForm with DataAnnotationsValidator or FluentValidation.IJSRuntime sparingly. Prefer Blazor bindings.[StreamRendering] for long-loading components.StateHasChanged() in lifecycle: Called automatically after lifecycle methods.OnInitialized or background task.@* UserList.razor *@
@page "/users"
@attribute [StreamRendering]
@inject IUserService UserService
<PageTitle>Users</PageTitle>
<h3>Users</h3>
@if (_users is null)
{
<p><em>Loading...</em></p>
}
else if (_users.Count == 0)
{
<p>No users found.</p>
}
else
{
<div class="user-grid">
@foreach (var user in _users)
{
<UserCard User="user" OnDelete="HandleDelete" />
}
</div>
}
@code {
private List<User>? _users;
protected override async Task OnInitializedAsync()
{
_users = await UserService.GetAllAsync();
}
private async Task HandleDelete(int userId)
{
await UserService.DeleteAsync(userId);
_users = await UserService.GetAllAsync();
}
}
@* UserCard.razor - Reusable component *@
<div class="card">
<h5>@User.Name</h5>
<p>@User.Email</p>
<button @onclick="() => OnDelete.InvokeAsync(User.Id)">Delete</button>
</div>
@code {
[Parameter, EditorRequired]
public User User { get; set; } = default!;
[Parameter]
public EventCallback<int> OnDelete { get; set; }
}
@* EditForm with validation *@
<EditForm Model="@_model" OnValidSubmit="HandleSubmit" FormName="CreateUser">
<DataAnnotationsValidator />
<ValidationSummary class="text-danger" />
<div class="mb-3">
<label class="form-label">Name</label>
<InputText @bind-Value="_model.Name" class="form-control" />
<ValidationMessage For="@(() => _model.Name)" />
</div>
<div class="mb-3">
<label class="form-label">Email</label>
<InputText @bind-Value="_model.Email" class="form-control" type="email" />
<ValidationMessage For="@(() => _model.Email)" />
</div>
<button type="submit" class="btn btn-primary" disabled="@_isSubmitting">
@if (_isSubmitting)
{
<span class="spinner-border spinner-border-sm"></span>
}
Submit
</button>
</EditForm>
@code {
private CreateUserModel _model = new();
private bool _isSubmitting;
private async Task HandleSubmit()
{
_isSubmitting = true;
await UserService.CreateAsync(_model);
_isSubmitting = false;
NavigationManager.NavigateTo("/users");
}
}
For lifecycle, state management, and JS interop: See references/REFERENCE.md.
aspnet-core | razor-pages | security
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer