Blazor(.net core 8)组件从未更新

问题描述 投票:0回答:1

我正在尝试定义一个充当引导警报包装器的组件。

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-server-side asp.net-core-8 blazor-component
1个回答
0
投票

目前您的代码无法正确编译,所以我不确定您如何调试所提供的代码。 当参数应该是公开的时,您却将参数声明为私有。

在更一般的层面上,您的代码过于复杂,因为您是 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();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.