如何使用输入参数动态更改 Blazor Webassembly 中的相同布局

How to dynamically change the Same Layout in Blazor Webassembly using an input parameter

我有这个用例,用于根据单击的剃刀页面更改父布局菜单项。 为了简单起见,在下面的示例布局代码中,我试图查看哪个子 Razor 页面正在尝试加载菜单项并根据它更改菜单项。
我试图避免创建多个布局文件。如果我理解正确的话布局在生命周期中只会加载一次除非你刷新浏览器 请让我知道这是否可能。

@inherits LayoutComponentBase
    <ul id="zMenu">
    @if (RouteName.Contains("/packing_sky/"))
    {
    <li class='title'>Sky Packing</li>
    <li><a href='/Packing_sky'>Pack</a></li>
    }
    else if (RouteName.Contains("/cartpick/")) {
    <li class='title'>Sky Packing</li>
    <li><a href='/CartPick'>Pack</a></li>
    }
    </div>
@code{
    public String RouteName= "";
    protected override void OnInitialized()
    {
        RouteName= "<from_razor_page>";
    }
}

提前致谢。

我认为有两种方法可以实现这种行为。

我会调用布局组件MainLayout

在第一种方法中,MainLayout 负责“知道”应该呈现什么 link。本质上,这是您已经完成的工作。 NavigationManager 具有当前 URL 所需的属性。所以需要注入。

@inject NavigationManager navManager

你说的也对,MainLayoutOnInitialized方法只会被调用一次。 (更珍贵的是,如果页面使用相同的布局,则不会再次调用)。但是,NavigationManager 有一个您可以订阅的活动。

@code{
    public String RouteName = "";

    private void HandleLocactionChanged(Object sender,LocationChangedEventArgs args)
    {
        RouteName = args.Location;
        //force an update of the UI, it might be necessary in some layouts and circumstances
        StateHasChanged();
    }

    protected override void OnInitialized()
    {
        RouteName = navManager.Uri;
        navManager.LocationChanged += HandleLocactionChanged;
    }

    public void Dispose()
    {
        navManager.LocationChanged -= HandleLocactionChanged;
    }
}

HandleLocactionChanged 方法中调用 StateHasChanged() 确保布局更新为新值。对于每种布局和每种情况,这可能不是必需的。我建议在没有它的情况下对其进行测试,如果它不起作用,请尝试使用 StateHasChanged().

我已经实现了 IDisposable 接口来取消订阅活动。这仅在您的应用程序具有多个布局时才有用。

第二种方法是使用服务在 MainLayout 和您的页面组件之间进行通信。就像页面“请求”显示 link.

如果您对此解决方案感兴趣,请告诉我,我会post。

谢谢,方法 #1 为我节省了很多代码重复。 我不得不在 HandleLocactionChanged 方法中做一个小改动。 所以我不得不再次重建 HTML 内容并通过 javascript 设置它,因为页面已经加载。

private void HandleLocationChanged(Object sender, LocationChangedEventArgs args)
{
    RouteName = args.Location;
    JSRuntime.InvokeVoidAsync(
                    "setHTML", new String[]{"zMenu", fetchMenuContent(RouteName)});
}