简体   繁体   English

Blazor 级联组件防止 StateHasChanged

[英]Blazor cascading component preventing StateHasChanged

So I'm new to Blazor and I've just found out about CascadingValue and their possible use for showing error messages.所以我是 Blazor 的新手,我刚刚发现了 CascadingValue 以及它们可能用于显示错误消息。 I am creating an Outlook Add In for saving mails and attachments in Sharepoint, so I'm dynamically retrieving the current Outlook mail using Office-js and JSInterop, such that my Add In always uses the selected mail.我正在创建一个 Outlook 插件,用于在 Sharepoint 中保存邮件和附件,因此我正在动态检索当前的 Outlook 使用 Office 的邮件和我选择的邮件。 But now that I'm trying to implement a cascading component for error messages I've run into problems with StateHasChanged.但是现在我正在尝试为错误消息实现级联组件,我遇到了 StateHasChanged 的问题。

Following code is my cascading error component:以下代码是我的级联错误组件:

<CascadingValue Value=this>
    @ChildContent
</CascadingValue>
<div class="error-container @(ErrorMessage == null ? "hidden" : "")">
    <span class="error-message">
        @ErrorMessage
    </span>
    <a class="dismiss-error" @onclick="DismissError">x</a>
</div>

@code {
    [Parameter]
    public RenderFragment ChildContent { get; set; }
    public string ErrorMessage { get; set; }

    public void ProcessError(Exception ex)
    {
        ErrorMessage = ex.Message;
        StateHasChanged();
    }

    public void DismissError()
    {
        ErrorMessage = null;
        StateHasChanged();
    }
}

And the component I'm having troubles with (atleast the important parts):我遇到问题的组件(至少是重要部分):

<div>
    {Showing details from OutlookMail here}
</div>
@code {
    [CascadingParameter] public Error Error { get; set; }
    public OutlookMail OutlookMail { get; set; }
    private static Action<OutlookMail> _receiveMailAction;
    protected override async Task OnInitializedAsync()
    {
        _receiveMailAction = UpdateMail;
        await base.OnInitializedAsync();
    }
    private void UpdateMail(OutlookMail mail)
    {
        InvokeAsync(() =>
        {
            OutlookMail = mail;
            StateHasChanged();
        });
    }
    [JSInvokable]
    public static void ReceiveMail(OutlookMail mail)
    {
        _receiveMailAction?.Invoke(mail);
    }
    public async Task MethodWithError()
    {
        try
        {
            await DoStuffWithPossibleError();
        }
        catch (Exception e)
        {
            Error.ProcessError(e);
        }
    }
}

Everything works fine until Error.ProcessError gets called and the error message is shown, after that StateHasChanged stops rerendering my component which gives inconsistent data to the users.一切正常,直到调用 Error.ProcessError 并显示错误消息,之后 StateHasChanged 停止重新渲染我的组件,从而为用户提供不一致的数据。

I am probably doing something wrong, since I can't really find anyone else with the same problem, but I'm not seeing it, so I'm hoping someone on here has a better understanding of where things are going wrong, or maybe even a better way of going about showing error messages if the problem is with using CascadingValue like this.我可能做错了什么,因为我真的找不到其他人有同样的问题,但我没有看到它,所以我希望这里的人能更好地了解哪里出了问题,或者也许如果问题是像这样使用 CascadingValue ,甚至是显示错误消息的更好方法。

All the help is appreciated.感谢所有帮助。

Edit 1: After some more looking into this, it seems that it's actually not updating OutlookMail, even when I move it outside of InvokeAsync.编辑 1:经过更多研究,它似乎实际上并没有更新 OutlookMail,即使我将它移到 InvokeAsync 之外。 So there might be something weird happening with instances of my component所以我的组件实例可能会发生一些奇怪的事情

After my first edit, I found out it was indeed a problem with instances, since I'm overwriting a static Action within OnInitialized, each time it creates a new instance, the old instances no longer works.在我第一次编辑后,我发现实例确实存在问题,因为我在 OnInitialized 中覆盖了 static 操作,每次创建新实例时,旧实例不再有效。 And the code which returned the error happened to have a auth dialog with a redirect callback to the same page, it closes directly after, but loading the page actually creates a new instance of my component, which in turn invalidates the one my user works with.并且返回错误的代码恰好有一个带有重定向回调到同一页面的身份验证对话框,它在之后直接关闭,但加载页面实际上会创建我的组件的一个新实例,这反过来又会使我的用户使用的那个无效. So I'll probably just have to create a singleton service that handles the incoming mail data, so that my component can always access the correct data.所以我可能只需要创建一个 singleton 服务来处理传入的邮件数据,这样我的组件就可以始终访问正确的数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Blazor StateHasChanged() 后组件未更新 - Blazor Component not updating after StateHasChanged() StateHasChanged/this.StateHasChanged 似乎对 Blazor 组件没有影响 - StateHasChanged/this.StateHasChanged doesn't seem to have effect on Blazor Component 使用 StateHasChanged 从父组件刷新 blazor 服务器子组件 - Refresh blazor server child component from parent component by using StateHasChanged blazor StateHasChanged 无法循环工作 - blazor StateHasChanged not working in a loop StateHasChanged 未更新组件 - StateHasChanged not updating component Blazor(客户端)StateHasChanged() 不更新页面 - Blazor (Client-side) StateHasChanged() not updating page Blazor StateHasChanged 和子参数(`await Task.Run(StateHasChanged);` vs `await InvokeAsync(StateHasChanged);`) - Blazor StateHasChanged and child parameters (`await Task.Run(StateHasChanged);` vs `await InvokeAsync(StateHasChanged);`) 将级联参数传递给从 JavaScript 呈现的 Blazor 组件 - Passing Cascading Parameters to Blazor component that rendered from JavaScript Blazor 中的级联下拉列表 - Cascading Dropdown in Blazor 在 Blazor 中,`await Task.Run(StateHasChanged)` 和 `await InvokeAsync(StateHasChanged)` 有什么区别? - In Blazor what is the difference between `await Task.Run(StateHasChanged)` and `await InvokeAsync(StateHasChanged)`?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM