简体   繁体   English

当我从函数调用时,在 onclick 事件之后 Blazor CascadingParameter 不会更新布局

[英]Blazor CascadingParameter won't update layout when I call it from a function, after an onclick event

I am trying to use CascadingParameter from my Layout to manage the "loading" of my website in a generic way.我正在尝试使用布局中的 CascadingParameter 以通用方式管理我网站的“加载”。
But I am not managing to stop the "loading" from the "OnValidSubmit" function of the "inherited page" EditForm, after I have called on "onclick" loading.但是,在调用“onclick”加载之后,我无法从“继承页面”EditForm 的“OnValidSubmit”函数中停止“加载”。

Let my show you.让我给你看。
In my MainLayout, I am managing to display a loading h2 or the content of a page whatever it is :在我的 MainLayout 中,我设法显示正在加载的 h2 或页面的内容,无论它是什么:

<CascadingValue Value="this">
@if (load == true)
{
    <h2>Loading...</h2>
} else
{
    @Body
}
</CascadingValue>

@code 
{ 
   public bool load = false;

   //---------------------------
   // Setters
   public void Loading()
   {
      load = true;
   }

   public void StopLoading()
   {
      load = false;
   }
}

In an other pages that inherits from that MainLayout, I have an EditForm that will check if username and password matches the database.在从该 MainLayout 继承的其他页面中,我有一个 EditForm 将检查用户名和密码是否与数据库匹配。
If no error, it should call the "Loading" function and then process the search in the database, and then Navigate to the home page.如果没有错误,则应调用“加载”函数,然后在数据库中进行搜索,然后导航到主页。
So I added the "Loading" function to the "onclick" of my EditForm and it correctly displays the loading h2 when I click on the button :因此,我将“加载”功能添加到我的 EditForm 的“onclick”中,当我单击按钮时,它会正确显示加载 h2:

    <EditForm Model="@user" OnValidSubmit="@TriggerLogin">
       <InputText id="name" placeholder="Email" @bind-Value="user.Username" inputmode="email" />
       <InputText id="password" placeholder="Mot de passe" @bind-Value="user.Password" type="password" inputmode="text" />
       <button class="button-pink" type="submit" @onclick="Layout.Loading">Se connecter</button>
   </EditForm>

And then process to make my research in the database with my "OnValidSubmit" function :然后使用我的“OnValidSubmit”函数在数据库中进行研究:

private async Task TriggerLogin()
{
    if (members.Login(user) == true)
    {
        // Do stuff with accesstoken
        Layout.StopLoading();
        NavigationManager.NavigateTo("/commandes");
    }
    else
    {
        Layout.StopLoading();
        error = "Wrong password or username";
    }
}

BUT my StopLoading() function is not updating my page !但是我的 StopLoading() 函数没有更新我的页面!
Even if my debugger says that I enterred correctly the function in the Layout, the layout is not entering the "else" of the html part and doesn't display the "@Body".即使我的调试器说我在布局中正确输入了函数,布局也不会输入 html 部分的“else”,也不会显示“@Body”。
I tried to use this.StateHasChanged() in the layout (the only place it worked) but I am searching for another solution because then it doesn't show the error message.我试图在布局中使用 this.StateHasChanged() (它唯一工作的地方)但我正在寻找另一个解决方案,因为它不会显示错误消息。

How can I do to force only the layout to refresh the html part ?我该怎么做才能强制布局刷新 html 部分? Thanks谢谢

Normally failing reload can be solved by using StateHasChanged();通常失败的重载可以通过使用StateHasChanged();来解决StateHasChanged(); So try所以试试

public void StopLoading()
{
   load = false;
   InvokeAsync(StateHasChanged);
}

--- Edit --- - - 编辑 - -

In case this make looses the local variables it would be an option to move those variables into a Service.如果这使局部变量丢失,则可以选择将这些变量移动到服务中。 In my sample I do it only for load and error but rest can be done like load.在我的示例中,我仅针对加载和错误执行此操作,但可以像加载一样完成其余操作。

public class LoadService {
    public bool Load {get;set;}
    public String ErrorMessage {get;set;}
}

Then change you code:然后改变你的代码:

@inject LoadService LoadService 
//... html part
@if (LoadService.Load== true)
{
    <h2>Loading...</h2>
}
//... html part
@code 
{ 
   //... html part
   public void StopLoading()
   {
      LoadService.Load = false;
      InvokeAsync(StateHasChanged);
    }
}

Set the error Message:设置错误信息:

private async Task TriggerLogin()
{
   if (members.Login(user) == true)
   {
       // Do stuff with accesstoken
       Layout.StopLoading();
       NavigationManager.NavigateTo("/commandes");
    }
    else
    {
        Layout.StopLoading();
        LoadService.ErrorMessage = "Wrong password or username";
    }
}

Don't forget to register the Service in Program.cs不要忘记在 Program.cs 中注册服务

builder.Services.AddSingleton<LoadService>();

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM