我想创建一个可以在网站上的不同页面之间访问的数据存储。我希望在每个页面上运行相同的代码。我认为最好将它放入其中,而不是放在每个页面上,MainLayout.razor
这样我就可以在那里编辑它。
但是每个页面都有一个范围数据的新实例,并且它不被共享。
如果我获取代码并手动将其插入到每个页面上,那么它就可以正常工作。
我的问题是:
- 为什么这在 中不起作用
MainLayout
?是范围不同吗?此页面还有其他问题吗? - 无需手动添加,让相同的代码在每个页面上运行的最佳方法是什么?
这是一个服务器项目(不是 WASM)
我试过:
in Program.cs :
builder.Services.AddScoped<ScopedDataStore>();
in MainLayout.razor:
@inject ScopedDataStore ScopedData
@inject NavigationManager _nav
...
protected override async Task OnInitializedAsync()
{
ScopedData.SetCurrentUrl(_nav.Uri);
}
and ScopedDataStore:
public class ScopedDataStore
{
private string CurrentUrl="";
private string PreviousUrl="";
public void SetCurrentUrl(string x)
{
PreviousUrl = CurrentUrl;
CurrentUrl = x;
}
public string GetLastUrl()
{
return this.GetHashCode().ToString();
}
}
这是在 MainLayout.razor 中:
<article class="content px-4">
@Body
<h1>Last URL : @ScopedData.GetLastUrl()</h1
</article>
编辑:
为了尝试解决这个问题,我创建了一个组件,并手动将其插入到每个页面上 - 然后我可以在一个地方编辑代码:
@inject ScopedDataStore ScopedData
@inject NavigationManager _nav
<h3>Last URL = @(ScopedData.GetLastUrl()) </h3>
@code {
protected override Task OnInitializedAsync()
{
ScopedData.SetNavigationManager(_nav);
Console.WriteLine("GlobalComp OnInitializedAsync");
ScopedData.PushCurrentUrl(_nav.Uri);
return Task.CompletedTask;
}
}
它未被共享的原因是您已将其配置为那样。由于Route.Razor是静态呈现的,因此每个导航事件都是到服务器的往返。
Layout
也在上下文中的服务器上静态呈现HttpRequest
,页面呈现两次,一次在服务器上静态呈现,然后第二次在 Blazor Hub SPA 上下文中呈现。将交互性配置为全局。
将App.razor更改为:
阅读并理解 - https://learn.microsoft.com/en-us/aspnet/core/blazor/components/render-modes?view=aspnetcore-8.0。
更新答案
您不能在静态页面和交互式页面之间共享作用域服务。
静态页面中的任何 Scoped 服务仅在 HttpRequest 的生命周期内存在。您无法获取最后一个 Url。
对于交互式页面,您可以按照您已完成的操作创建一个组件或创建一个自定义的
ComponentBase
。以下是如何进行自定义
ComponentBase
。我已将代码添加到而
SetParametersAsync
不是OnInitializedAsync
因为它会在任何正常生命周期代码之前执行,并且您不太可能覆盖SetParametersAsync
和忘记调用base
。你可以像这样使用: