如何在 Blazor 中的页面之间传递对象

XDb*_*boy 7 c# razor blazor

我有我的主页,在此页面中我有一个包含对象的列表。通过 foreach 我得到了它的项目,如果您单击按钮,我想将项目传递到另一个页面。我怎样才能通过呢?

Bar*_*ers 6

如果它是一个简单的值(int, string),那么您可以将此值作为路径或查询参数传递到其他页面:

来自页面:

<ul>
  <li><a href="/page/a">A</a></li>
  <li><a href="/page/b">B</a></li>
  <li><a href="/page/c">C</a></li>
</ul>
Run Code Online (Sandbox Code Playgroud)

到页面:

@page "/page/{PathParam}"

<h1>Page @this.PathParam</h1>

@code {
  [Parameter]
  public string PathParam { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果数据更复杂,请尝试使用此处描述的选项之一:https://learn.microsoft.com/en-us/aspnet/core/blazor/state-management ?view=aspnetcore-5.0&pivots= webAssembly服务器端存储浏览器存储内存状态容器服务


ssa*_*mko 6

对于更复杂的对象,最好使用StateContainer(在内存解决方案中)。

注册您的StateContainer姓名MauiProgram.cs

builder.Services.AddScoped<StateContainer>();
Run Code Online (Sandbox Code Playgroud)

其中StateContainer.cs包含:

public readonly Dictionary<int, object> ObjectTunnel = new();
Run Code Online (Sandbox Code Playgroud)

然后作为一个例子我将ComplexObject.cs在哪里创建

public class ComplexObject
{
    public int Count = 0;
    public string Color = string.Empty;
}
Run Code Online (Sandbox Code Playgroud)

然后当您有页面例如Index.razor并且Counter.razor您想ComplexObject从一个页面发送到另一个页面时,然后Index.razor注入StateContainer

并调用类似的内容:

public void OpenCounterWithData()
{
    var data = new ComplexObject{Count = 3, Color="red"}
    _stateContainer.ObjectTunnel.Add(data.GetHashCode(), data)

    _navigationManager.Navigate($"counter/{data.GetHashCode()}")
}
Run Code Online (Sandbox Code Playgroud)

并在Counter.razor您指定页面中,例如:

@page "/counter/{SetHashCode:int}"
Run Code Online (Sandbox Code Playgroud)

和输入参数:

[Parameter] public int SetHashCode { get; set; }
Run Code Online (Sandbox Code Playgroud)

例如,OnInitialized您可以从中提取值StateContainer

protected override void OnInitialized()
{
    var data = (ComplexObject) _stateContainer.ObjectTunnel[SetHashCode];
}
Run Code Online (Sandbox Code Playgroud)

之后您还应该从ObjectTunnel. 这基本上就是整个流程。


优化:

  • 我创建了一些扩展方法来优化流程

StateContainerExtensions.cs

public static class StateContainerExtensions
{
    public static int AddRoutingObjectParameter(this StateContainer stateContainer, object value)
    {
        stateContainer.ObjectTunnel[value.GetHashCode()] = value;
        return value.GetHashCode();
    }

    public static T GetRoutingObjectParameter<T>(this StateContainer stateContainer, int hashCode)
    {
        return (T) stateContainer.ObjectTunnel.PopValue(hashCode);
    }
}
Run Code Online (Sandbox Code Playgroud)

DictionaryExtensions.cs

public static class DictionaryExtensions
{
    public static TValue PopValue<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey keyName) where TKey : notnull
    {
        var value = dictionary[keyName];
        dictionary.Remove(keyName);
        return value;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用这些扩展方法,您可以

_stateContainer.ObjectTunnel.Add(data.GetHashCode(), data)
Run Code Online (Sandbox Code Playgroud)

仅使用:

_stateContainer.AddRoutingObjectParameter(_trainingSet);
Run Code Online (Sandbox Code Playgroud)

而是:

var data = (ComplexObject) _stateContainer.ObjectTunnel[SetHashCode];
_stateContainer.ObjectTunnel.Remove(SetHashCode);
Run Code Online (Sandbox Code Playgroud)

使用:

var data = _stateContainer.GetRoutingObjectParameter<ComplexObject>(SetHashCode);
Run Code Online (Sandbox Code Playgroud)

  • @RamilAliyev007 是和否。Blazor 的类型(服务器与 WASM)很重要。因为在 WASM 中 Singleton=Scoped。如果 Blazor 服务器将其设置为作用域,则正确的方法是为每个用户/电路使用状态容器,而不是在所有用户之间使用。谢谢你的提醒。 (2认同)