Компонент не перерисовывается после вызова StateHasChanged - PullRequest
1 голос
/ 01 марта 2020

Я прочитал статью " 3 способа связи между компонентами в Blazor " и попытался сделать то же самое. У меня есть компонент сообщения под @body и в зависимости от действий пользователя в компоненте @body сообщение должно быть изменено

@inject ClientMessage clientMessage
@inherits LayoutComponentBase
@using Site.Shared.Components

<div class="sidebar">
<AdminMenu />
</div>

<div class="main">
    <div class="content px-4">
        @Body
    </div>
   <Message/>
</div>

@code
{
    protected async Task ChangeState()
    {
        await InvokeAsync(StateHasChanged);
    }

    protected override void OnInitialized()
    {
        clientMessage.MsgChange += ChangeState;
    }
 }

Компонент сообщения:

@inject ClientMessage clientMessage
<div style="@(IsVisble ? "display:block" : "display:none")" class="@MsgClass" role="alert">
    @if (clientMessage != null)
    {
        @clientMessage.Message
    }
</div>

@code {

    public bool IsVisble
    {
        get
        {
            if (string.IsNullOrEmpty(@clientMessage.Message))
            {
                return false;
            }

            return true;
        }
    }

    public string MsgClass
    {
        get
        {
            if (clientMessage == null)
            {
                return string.Empty;
            }

            string msgClass;

            switch (clientMessage.MsgType)
            {
                case EMsgType.Info:
                    msgClass = "alert alert-info";
                    break;
                case EMsgType.Success:
                    msgClass = "alert alert-success";
                    break;
                case EMsgType.Warning:
                    msgClass = "alert alert-warning";
                    break;
                case EMsgType.Error:
                    msgClass = "alert alert-danger";
                    break;
                case EMsgType.NoMsg:
                default:
                    msgClass = string.Empty;
                    break;
            }

            return msgClass;
        }
    }
}

Класс сообщения

public class ClientMessage
{
    public event Func<Task> MsgChange;

    public ClientMessage(string msg, EMsgType msgType)
    {
        this.Message = msg;
        this.MsgType = msgType;
        NotifyStateChanged();
    }

    public void SetMsg(string msg, EMsgType msgType)
    {
        this.Message = msg;
        this.MsgType = msgType;
        NotifyStateChanged();
    }

    public string Message { get; set; }

    public EMsgType MsgType { get; set; }

    private void NotifyStateChanged()
    {
        if (MsgChange != null)
        {
            MsgChange.Invoke();
        }
    }
}

Класс ClientMessage внедряется DI как одноэлементный. Если я вызываю SetMsg (newMsgm, msgType) в компонентах @body, то вызывается метод ChangeState (), но ничего не происходит, я имею в виду, что компонент не отображается повторно. Если я вместо «InvokeAsyn c» использую «Invoke», у меня появляется ошибка «Текущий поток не связан с Dispatcher. Используйте InvokeAsyn c () для переключения выполнения на Dispatcher при запуске рендеринга или состояния компонента.». Если я перезагрузить страницу, я вижу сообщение.

Что я делаю не так и как заставить принудительно перерисовать компонент сообщения?

1 Ответ

1 голос
/ 07 марта 2020

Я решил эту проблему. Может быть, это кому-то поможет.

Я локализовал проблему - когда @body был изменен после вызова NavigationManager.NavigateTo ("some_page") StateHasChanged () не повторно отображал компонент сообщения. Я пробовал разные места, где я могу запустить StateHasChanged (), и если я переместил его в Message.razor, он начнет работать как положено.

лучше читать документацию в начале , чем статьи :)

...