我正在尝试定义一个充当引导警报包装器的组件。
BootstrapAlert.razor
<div class="alert alert-@AlertType d-@(string.IsNullOrEmpty(Message) ? "none" : "block")" role="alert">
@Message
</div>
@code {
[ParameterAttribute]
private string AlertType { get; set; } = "info"; // Default alert type
[ParameterAttribute]
private string? Message { get; set; }
// Method to update the alert type and message
public async Task ShowAsync(string alertType, string message)
{
AlertType = alertType;
Message = message;
await InvokeAsync(StateHasChanged);
}
// Method to hide the alert
public async Task HideAsync()
{
Message = null;
await InvokeAsync(StateHasChanged);
}
protected override async Task OnParametersSetAsync()
{
//Message is ALWAYS null here
await base.OnParametersSetAsync();
}
}
页码:
<form class="row" @onsubmit="SubmitForm" @onsubmit:preventDefault>
<Alert @ref=SaveAlert></Alert>
<button type="submit">Save</button>
</form>
@code {
private Alert? SaveAlert;
private async Task SubmitForm()
{
try
{
await SetIsLoading(true); //DISPLAYS A LOADING SPINNER
if (SaveAlert != null) await SaveAlert.HideAsync();
//.......
if (SaveAlert != null) await SaveAlert.ShowAsync("success", "OK");
}
catch (Exception ex)
{
if (SaveAlert != null) await SaveAlert.ShowAsync("danger", ex.Message);
}
finally
{
await SetIsLoading(false);
}
StateHasChanged();
}
}
警报组件永远不会更新,在“OnParametersSetAsync”中,“Message”参数始终为空。
我尝试过这些方法的非异步版本,将“StateHasChanged”放在任何地方,不调用“隐藏”方法,还删除了 [ParameterAttribute] 属性,以便将其用作常规变量,但似乎对我不起作用
我是 blazor 的新手,所以我不知道还有什么相关的。我将该应用程序用作 RenderMode="Server"
我做错了什么?
目前您的代码无法正确编译,所以我不确定您如何调试所提供的代码。 当参数应该是公开的时,您却将参数声明为私有。
在更一般的层面上,您的代码过于复杂,因为您是 Blazor 新手,并且仍在获取必要的知识。
这是一种使用绑定构建警报的更简洁的方法。 使用
@ref
捕获实例是可以的,但如果可能的话,最好避免组件之间的这种紧密耦合。
用于保持警报状态的数据对象。
public readonly record struct AlertData(bool Show, string AlertType, string Message);
警报剃刀
<div hidden="@_hidden" class="@_css" role="alert">
@this.Value.Message
</div>
@code {
// These are the bind parameters
[Parameter] public AlertData Value { get; set; }
[Parameter] public EventCallback<AlertData> ValueChanged { get; set; }
private string _css => $"alert alert-{this.Value.AlertType}";
private bool _hidden => !this.Value.Show;
// If you had a dismiss button
private void Dismiss()
{
this.ValueChanged.InvokeAsync(new AlertData(false, string.Empty, string.Empty));
}
}
演示:
@page "/"
<PageTitle>Home</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
<Alert @bind-Value="_alertData" />
<div class="m-2">
<button class="btn btn-primary" @onclick="this.SubmitForm">Save</button>
</div>
@code {
private AlertData _alertData = new(false, string.Empty, string.Empty);
private bool _toggleState;
private async Task SubmitForm()
{
_alertData = new(false, string.Empty, string.Empty);
// UI Event Handler will render the component here and create a render cascade on sub-components with changed parameters
await SetIsLoading(true);
if (_toggleState)
_alertData = new(true, "success", "Ok");
else
_alertData = new(true, "danger", "Failed");
_toggleState = !_toggleState;
await SetIsLoading(false);
// UI Event Handler will render the component here and create a render cascade on sub-components with changed parameters
}
private async ValueTask SetIsLoading(bool show)
{
// Do whatever
await Task.Yield();
}
}