Blazor WASM在集合更改时更新导航

Blazor WASM在集合更改时更新导航,blazor,blazor-webassembly,blazor-routing,Blazor,Blazor Webassembly,Blazor Routing,我计划的设计是有一个带有4个按钮的主页。当用户单击其中任何一个按钮时,它会将一个项目添加到导航中。我使用这个单例来管理状态 public class StateManager { public event Action NewPlanAdded; public void AddPlan() { NewPlanAdded?.Invoke(); } } 我将这个单例注入子组件 @inject StateManager StateManager &l

我计划的设计是有一个带有4个按钮的主页。当用户单击其中任何一个按钮时,它会将一个项目添加到导航中。我使用这个单例来管理状态

public class StateManager
{
    public event Action NewPlanAdded;
    public void AddPlan()
    {
        NewPlanAdded?.Invoke();
    }
}
我将这个单例注入子组件

@inject StateManager StateManager

<button class="btn btn-primary" @onclick="CreateNewPlan">Create New Plan</button>

@code {
    private void CreateNewPlan()
    {
        StateManager.AddPlan();
    }
}
@inject StateManager StateManager

<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
    <ul class="nav flex-column">
        @foreach (var item in Items)
        {
            <li class="nav-item px-3">
                <NavLink class="nav-link" href="@item.Item1" >
                    <span class="@item.Item2" aria-hidden="true"></span> @item.Item3
                </NavLink>
            </li>
        }        
    </ul>
</div>

@code {
    IList<Tuple<string, string, string>> Items { get; set; }

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        StateManager.NewPlanAdded += NewPlanAdded;
        Items = new List<Tuple<string, string, string>>
        {
            new Tuple<string, string, string>("", "oi oi-home", "Home")
        };
    }

    public void Dispose()
    {
        StateManager.NewPlanAdded -= NewPlanAdded;
    }

    private void NewPlanAdded()
    {
        Items.Add(new Tuple<string, string, string>("plan", "oi oi-plus", "Plan (unsaved)"));
    }
}
@inject StateManager StateManager
创建新计划
@代码{
私有void CreateNewPlan()
{
StateManager.AddPlan();
}
}
和导航组件

@inject StateManager StateManager

<button class="btn btn-primary" @onclick="CreateNewPlan">Create New Plan</button>

@code {
    private void CreateNewPlan()
    {
        StateManager.AddPlan();
    }
}
@inject StateManager StateManager

<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
    <ul class="nav flex-column">
        @foreach (var item in Items)
        {
            <li class="nav-item px-3">
                <NavLink class="nav-link" href="@item.Item1" >
                    <span class="@item.Item2" aria-hidden="true"></span> @item.Item3
                </NavLink>
            </li>
        }        
    </ul>
</div>

@code {
    IList<Tuple<string, string, string>> Items { get; set; }

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        StateManager.NewPlanAdded += NewPlanAdded;
        Items = new List<Tuple<string, string, string>>
        {
            new Tuple<string, string, string>("", "oi oi-home", "Home")
        };
    }

    public void Dispose()
    {
        StateManager.NewPlanAdded -= NewPlanAdded;
    }

    private void NewPlanAdded()
    {
        Items.Add(new Tuple<string, string, string>("plan", "oi oi-plus", "Plan (unsaved)"));
    }
}
@inject StateManager StateManager
    @foreach(项目中的var项目) {
  • @项目1.3
  • }
@代码{ IList项{get;set;} 受保护的重写异步任务OnInitializedAsync() { wait base.OnInitializedAsync(); StateManager.NewPlanAdded+=NewPlanAdded; 项目=新列表 { 新元组(“,“oi oi home”,“home”) }; } 公共空间处置() { StateManager.NewPlanAdded-=NewPlanAdded; } 私有void NewPlanAdded() { 添加(新元组(“计划”、“oi oi plus”、“计划(未保存)”); } }

问题在于,新列表项只有在导航组件隐藏并再次显示后才会显示。当集合更改时,如何让foreach刷新?

您应该通知组件状态已更改,执行
InvokeAsync(StateHasChanged)

private void NewPlanAdded()
{
添加(新元组(“计划”、“oi oi plus”、“计划(未保存)”);

InvokeAsync(statehaschange);//我看到几个示例显示
InvokeAsync(()=>statehaschange());
。为什么您的方法更好?@JHBonarius也是一样。InvokeAsync将函数作为参数,statehaschange是函数。您可以将statehaschange作为参数发送,或者创建一个新的匿名函数
()=>statehaschange()
并发送匿名函数。@JHBonarius这是同样的事情,字符更少,使它更易于阅读。谢谢!我正在将它集成到我们键入的代码中,所以字符越少越好;)给我留下了更多的字符以便输入注释:Pby的方式,我仍然不确定我是否应该
等待
InvokeAsync
或不…思考如果我只是触发并忘记,可能会发生什么最坏的情况…当第一次调用尚未完成时,第二个线程调用它可能会出现并发异常?