NavigationManager.NavigateTo()在运行方法后不起作用。

huangapple go评论70阅读模式
英文:

NavigationManager.NavigateTo() does not work after running a method

问题

I understand your request. Here's the translated code part:

迫切寻求帮助...

我有一个.Net7服务器端的Blazor应用程序,它正在按预期工作(某种程度上)。我添加了一个登录页面,用户在屏幕上输入用户名和密码,然后点击提交按钮。接下来应该发生以下情况:

- 检查用户名和密码中是否有数据,如果没有则显示警报
- 运行一个触发数据库上的存储过程的方法(我使用ADO而不是EF)
- 计算```List<Family>```中的项目数量(此项目在上面的方法中创建)
- 转到一个新页面,如果计数大于0,则显示警报

问题似乎出现在方法中。当我运行代码时,```List<Family>```从数据库中填充。我可以在Razor组件中进行检查,可以看到列表中是否有超过1个项目。当检查完成后,我可以触发导航方法或警报方法,它们会在调试中运行。问题是在UI中,屏幕不会更改为新页面,或者在预期显示警报时不会显示。

没有显示错误消息,只有原始屏幕。

哦,你可能会认为这是导航或警报方法的问题!如果我将导航和/或警报方法**放在**```GetFamilies()```方法之前(该方法填充了```list<Family>```),导航和/或警报就可以正常工作。

我不明白的是为什么 :( 我已经删除了所有异步方法,因此应该同步运行。我已经多次重写了这个代码,包括使用缓存,使用异步,使用```Task.WaitAll()```等多种方法。似乎在应用程序需要联系数据库的地方,虽然代码已运行,但它不会更新UI。我甚至检查了线程,并且在进入```GetFamilies()```时与退出和方法执行期间是相同的。

请注意,```ReturnData.GetFamilies()```方法运行正常,不使用任何异步内容,与此Razor页面中的```GetFamilies()```方法不同。

有人可以建议我哪里错了吗?

Blazor组件中的表单:

请使用您的邀请提供的用户名和密码。



```

身份验证方法:

private void Authenticate()
{
    if (!ValidLoginDetails())
    {
        return;
    }
    GetFamilies();
    if(Families.Count > 0)
    {
        Navigate();
    }
    else
    {
        Alert("您的凭据未被识别");
    }
}

获取家庭方法:

private void GetFamilies()
{
    string localConnectionString = config.GetConnectionString("SQLServerConnection");
    Families = ReturnData.GetFamilies(localConnectionString, LocalLogin);
}

导航和警报方法:

private void Navigate()
{
    navManager.NavigateTo("/ufr", true, true);
}

private void Alert(string argMessage)
{
    js.InvokeVoidAsync("alert", argMessage);
}

希望这能帮助你解决问题。如果需要进一步的帮助,请随时提出。

<details>
<summary>英文:</summary>

looking desperately for some help...

I have a .Net7 server-side Blazor app that is working as expected (sort of). I have added a login page where the user puts in their Username and Password into the screen and hits submit. What should happen then is

 - Check there is data in the Username and Password, displaying an alert if not
 - Run a method that triggers a Stored Procedure on the database (I use ADO and not EF)
 - Count the number of items in the ```List&lt;Family&gt;``` (this is created in the above method)
 - Navigate to a new page where the count is greater than 0 or display an alert if not

OK. The problem lies in the method somehow. When I run the code, the ```List&lt;Family&gt;``` is populated from the database. I can do the check in the razor component and I can see I have more than 1 item in the list or not. When the check is done, I can then either trigger the navigate method or the alert methods and it runs through those in debug. The issue is that in the UI the screen does not change to the new page or when an alert is expected does not display.

No error messages are displayed just the originating screen.

Ah, you may think, this is a problem with the Navigate or Alert methods!!! Well, if I place the navigate and/or the alert methods **before** the ```GetFamilies()``` method (which populates the ```list&lt;Family&gt;``` the navigation and/or the alert works fine.

What I don&#39;t understand is why :( I have removed all the async methods so it should run synchronously. I have re-coded this loads of times and ways including using a cache, using async, using ```Task.WaitAll()```. It seems where the app needs to contact the database something happens that means although the code is run it doesn&#39;t update the UI. I have even checked the Threads and going into the ```GetFamilies()``` is the same coming out and during the method.

Note that the ```ReturnData.GetFamilies()``` method works fine and does not use anything async and is a different method to ```GetFamilies()``` in this razor page.

Can anyone suggest where I am going wrong?

Form in the Blazor component

<form>
<div class="mb-3">
<label for="userName" class="form-label">Username</label>
<input @bind="LocalLogin.UserName" type="text" class="form-control" id="userName" aria-describedby="userNameHelp" placeholder="User Name">
<div id="userNameHelp" class="form-text">Please use the username and password provided with your invite.</div>
</div>
<div class="mb-3">
<label for="userPassword" class="form-label">Password</label>
<input @bind="LocalLogin.Password" type="password" class="form-control" id="userPassword" placeholder="Password">
</div>
<button type="submit" class="btn btn-primary" @onclick="() => Authenticate()">Submit</button>
</form>

Authenticate Method
private void Authenticate()
{
    if (!ValidLoginDetails())
    {
        return;
    }
    GetFamilies();
    if(Families.Count &gt; 0)
    {
        Navigate();
    }
    else
    {
        Alert(&quot;Your credentials have not been recognised&quot;);
    }
}
Get Families method
private void GetFamilies()
{
    string localConnectionString = config.GetConnectionString(&quot;SQLServerConnection&quot;);
    Families = ReturnData.GetFamilies(localConnectionString, LocalLogin);
}
Navigate and Alert Methods
private void Navigate()
{
    navManager.NavigateTo(&quot;/ufr&quot;, true, true);
}

private void Alert(string argMessage)
{
    js.InvokeVoidAsync(&quot;alert&quot;, argMessage);
}

</details>


# 答案1
**得分**: 3

替换:

```html
&lt;button type=&quot;submit&quot; ...&gt;Submit&lt;/button&gt;

为:

&lt;button type=&quot;button&quot; ...&gt;Submit&lt;/button&gt;

您有一个&lt;form&gt;,其中包含一个实际的提交按钮。这将执行实际的POST请求到您的服务器,并且不会被处理。

更好的做法是使用&lt;EditForm&gt;,但这是一个选择性的问题。

英文:

Replace

&lt;button type=&quot;submit&quot; ...&gt;Submit&lt;/button&gt;

with

&lt;button type=&quot;button&quot; ...&gt;Submit&lt;/button&gt;

You have a &lt;form&gt; with an actual submit button. That will do an actual POST to your server and that won't be handled.

Even better would be using an &lt;EditForm&gt; but that's a matter of choice.

huangapple
  • 本文由 发表于 2023年7月3日 04:57:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76600771.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定