在C# Blazor中如何将一个List传递到页面?

3

我有第二个页面,接收以下参数:

@page "/newrecord/{Employees}"
@inject HttpClient http

<h1>@Employees.Count</h1>

@code {
    [Parameter]
    public List<Model.Employees> Employees{ get; set; }
}

在我的主页上,当点击按钮时,我会传递列表,如下所示:

List<Model.Employees> selected { get; set; }

private void OnAddRecord()
    {
        NavigationManager.NavigateTo($"newrecord/{this.selected}");
    }

当单击按钮时,我会收到一个错误,并且可以看到 URL 形成的方式如下:

enter image description here

如何将此对象传递到第二页?我是否必须使用 LocalStorage?或者使用其他类型的对象?

1
是的,您必须使用状态对象保存列表并传递ID到页面以检索此列表。您可以使用单例在内存中执行此操作,或将列表存储在会话存储或本地存储中。 - agua from mars
1
我认为,列表的路由约束不支持 https://learn.microsoft.com/en-us/aspnet/core/blazor/routing?view=aspnetcore-3.1#route-constraints。您可以尝试使用Blazor子组件、Razor Page或者@aguafrommars在评论中提到的方法。 - Mofaggol Hoshen
1个回答

6
实现该问题的可行解决方案是在一个服务中实现状态模式和通知模式,以保持对象状态并通知订阅对象更改。因此,您可以创建一个服务,缓存员工集合,允许对象(在这种情况下为主要组件)将员工添加到该集合中,并通知订阅者(newrecord)这一事实,从而使其能够访问该集合,或更好地将其作为事件参数对象从服务传递给订阅者对象。以下是如何实现状态模式和通知模式的基本示例。请注意:此示例运行良好,且不是为答案而创建的。

Child1.razor

@inject NotifierService Notifier
@implements IDisposable

@inject IState State

<hr />
<input type="checkbox" @bind="State.ShowEasterEggs" />Show Easter Eggs
<hr />

<h1>User puts in something</h1>
<input type="text" @bind="@value" />
<button @onclick="@AddValue">Add value</button>

@foreach (var value in Notifier.ValuesList)
{
   <p>@value</p>
}


@code {
private string value { get; set; }

public void AddValue()
{
    Notifier.AddTolist(value);

}

public async Task OnNotify()
{
    await InvokeAsync(() =>
    {
        StateHasChanged();
    });
}


protected override void OnInitialized()
{
    Notifier.Notify += OnNotify;
}
public void Dispose()
{
    Notifier.Notify -= OnNotify;
}
}

Child2.razor

@inject NotifierService Notifier
@implements IDisposable

@inject IState State

<hr />
@if (State.ShowEasterEggs)
{
  <span>EASTER EGGS SHOWN</span>
}

<hr />

<h1>Displays Value from service and lets user put in new value</h1>

<input type="text" @bind="@value" />

<button @onclick="@AddValue">Set Value</button>

@code {
  private string value { get; set; }


 public void AddValue()
 {
    Notifier.AddTolist(value);

 }

 protected override void OnInitialized()
 {
    State.Notify += OnNotify;

 }

 public void OnNotify()
 {
    InvokeAsync(() =>
    {
        StateHasChanged();
    });
 }


 public void Dispose()
 {
    State.Notify -= OnNotify;
 }

}

NotifierService.cs

 using System;
 using System.Collections.Generic;
 using System.Net.Http;
 using System.Threading.Tasks;
 using ChildComponentsCommunication.Shared;
 using Microsoft.AspNetCore.Components;

 namespace ChildComponentsCommunication
{
    public class NotifierService
    {
        private readonly List<string> values = new List<string>();
        public IReadOnlyList<string> ValuesList => values;

        public NotifierService()
        {

        }

        public async void AddTolist(string value)
        {
            values.Add(value);
            if (Notify != null)
            {
               await Notify?.Invoke();
            }

        }

        public event Func<Task> Notify;
  }
}

IState.cs

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;

 namespace ChildComponentsCommunication
{
  public interface IState
  {
    event Action Notify;
    bool ShowEasterEggs { get; set; }
  }
  public class State : IState
  {
    public event Action Notify;

    bool showEggs = false;
    public bool ShowEasterEggs
    {
        get => showEggs;
        set
        {
            if (showEggs != value)
            {
                showEggs = value;

                if (Notify != null)
                {
                    Notify?.Invoke();
                }
            }
        }
      }

   }
}

Startup.ConfigureServices

 services.AddSingleton<IState, State>();
 services.AddScoped<NotifierService>();

希望这个能够运行...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接