Blazor:从布局访问参数

时间:2019-09-05 18:59:16

标签: blazor blazor-server-side

如何从布局访问页面的route参数?

我有一个页面接受如下所示的route参数:

@page /my-page/{Slug}

在共享布局中渲染标记时,我需要访问Slug的值。

我曾尝试像以下所示在布局文件中实现OnParametersSet,但未设置该值。它仅在页面级别分配。

@inherits LayoutComponentBase

<div class="sidebar">
    <NavMenu />
</div>

<div class="main">
    <div class="top-row px-4">
            @this.Slug   <<<<------ display the parameter
    </div>

    <div class="content px-4">
        @Body
    </div>
</div>

@code
{
    [Parameter]
    public string Slug { get; set; }

    protected override void OnParametersSet()
    {
        // Slug is always null :-/
    }
}

2 个答案:

答案 0 :(得分:7)

您可以通过CascadingParameters使RouteData对所有组件可用。在您的App.razor中,执行以下操作:

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <CascadingValue Value="@routeData">
            <RouteView RouteData="@routeData" DefaultLayout="@typeof(MyLayout)" />
        </CascadingValue>
    </Found>
</Router>

然后,在需要RouteData的所有组件中,只需添加:

@code
{
    [CascadingParameter]
    RouteData RouteData { get; set; }
}

该值将自动填充。

答案 1 :(得分:2)

经过一番摸索,我提出了以下解决方案。可能可以在.razor文件中完成所有操作,但是我在“隐藏代码”文件中实现了一些混乱,以隐藏似乎很麻烦的东西。

在Layout实例中,如果您覆盖OnParametersSet,并深入Body.Target,则会发现RouteData,其中包含route参数。然后,您可以将这些值传播到布局中的子组件。

我们希望对版式可用的带有“ Slug”参数的页面

@page "/mypage/{Slug}"

布局.razor文件

@inherits Components.MyLayoutBase

<div class="sidebar">
    <!-- Pass the Slug property to the NavMenu's Parameter -->
    <MyNavMenu Slug="@Slug" />
</div>

<div class="main">
    <div class="top-row px-4"></div>    
    <div class="content px-4">
        @Body
    </div>
</div>

后面的布局代码

public class MyLayoutBase : LayoutComponentBase
{
    public string Slug { get; set; }

    protected override void OnParametersSet()
    {
        // pull out the "Slug" parameter from the route data
        object slug = null;
        if ((this.Body.Target as RouteView)?.RouteData.RouteValues?.TryGetValue("Slug", out slug) == true)
        {
            Slug = slug?.ToString();
        }
    }
}

导航菜单

<div class="top-row pl-4 navbar navbar-dark">
</div>

<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
    <ul class="nav flex-column">
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
                <span class="oi oi-home" aria-hidden="true"></span> Home
            </NavLink>
        </li>
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="@($"/some-page/{Slug}/foo")">
                <span class="oi oi-home" aria-hidden="true"></span> Foo
            </NavLink>
        </li>
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="@($"/some-page/{Slug}/bar")">
                <span class="oi oi-home" aria-hidden="true"></span> Bar
            </NavLink>
        </li>
    </ul>
</div>

@code {

    [Parameter]
    public string Slug { get; set; }

    bool collapseNavMenu = true;

    string NavMenuCssClass => collapseNavMenu ? "collapse" : null;

    string setupUrl = string.Empty;

    void ToggleNavMenu()
    {
        collapseNavMenu = !collapseNavMenu;
    }
}