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

如何使用输入参数动态更改Blazor Webassembly中的相同布局,blazor,blazor-server-side,blazor-client-side,blazor-webassembly,Blazor,Blazor Server Side,Blazor Client Side,Blazor Webassembly,我有一个用例,用于根据单击的razor页面更改父布局菜单项。 为了简单起见,在下面的示例布局代码中,我尝试查看哪个子Razor页面正在尝试加载菜单项,并基于此更改菜单项。 我试图避免创建多个布局文件。如果我理解正确,除非刷新浏览器,否则布局在生命周期中只加载一次 请让我知道这是否可能 @inherits LayoutComponentBase <ul id="zMenu"> @if (RouteName.Contains("/packin

我有一个用例,用于根据单击的razor页面更改父布局菜单项。 为了简单起见,在下面的示例布局代码中,我尝试查看哪个子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>";
    }
}
@继承LayoutComponentBase
    @if(RouteName.Contains(“/packing\u sky/”) {
  • 天空包装
  • } else if(RouteName.Contains(“/cartpick/”){
  • 天空包装
  • } @代码{ 公共字符串RouteName=“”; 受保护的覆盖无效OnInitialized() { RouteName=“”; } }

提前感谢。

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

我将调用布局组件
MainLayout

在第一种方法中,
MainLayout
负责“知道”应该呈现什么链接。本质上,这是你已经做过的。
NavigationManager
具有当前URL所需的属性。所以你需要注射它

@inject NavigationManager navManager
同样正确的是,
mainloayout
OnInitialized
方法将只调用一次。(更重要的是,如果页面使用相同的布局,则不会再次调用它)。但是,
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;
    }
}
handleLocationChanged
方法中调用
StateHasChanged()
,确保用新值更新布局。这可能不是每个布局和每个环境都需要的。我建议在不使用它的情况下进行测试,如果它不起作用,请使用
statehaschange()
进行尝试

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

第二种方法是使用服务在
MainLayout
和页面组件之间进行通信。这就像页面“请求”显示链接一样

如果您对这个解决方案感兴趣,请告诉我,我会发布它。

谢谢,这种方法#1为我节省了大量代码重复。 我不得不对handleLocationChanged方法做一个小改动。 因此,我必须重新构建HTML内容,并通过javascript进行设置,因为页面已经加载

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

能否尝试调用
statehaschange()
而不是调用javascript函数?它不需要额外的javascript就可以工作。太棒了!!只是尝试了一下,效果如预期。我现在不需要任何修补JS代码。再次感谢!太好了。我已经更新了我的原始答案。如果你能接受这个答案,这样别人就能更容易地找到解决方案,那就太好了。