如何在Blazor组件中访问当前路由

6
我有一个ASP(dot)NET Web应用程序,它有一个简单的导航栏。我试图使用Blazor组件来更改导航栏,并在页面处于活动状态时增加左边框的宽度。到目前为止,我使用了一个switch语句,该语句基于表示当前页面的字符串进行切换。我的问题是我找不到一种编程方式来查找站点所在的当前URL。我已经多次搜索了这个问题,但每个解决方案都没有起作用,甚至使用HttpContext也没有起作用。
switch (CurrUrl)
{
case "Index":
    <header>
        <div>
            <nav>
                <ul class="main-menu">
                    <li id="CurPage">Home</li>
                    <li class="menu-item">Shop</li>
                    <li class="menu-item">FAQ</li>
                    <li class="menu-item">About</li>
                </ul>
            </nav>
        </div>
    </header>
    break;
case "Shop":
    <header>
        <div>
            <nav>
                <ul class="main-menu">
                    <li class="menu-item">Home</li>
                    <li id="CurPage">Shop</li>
                    <li class="menu-item">FAQ</li>
                    <li class="menu-item">About</li>
                </ul>
            </nav>
        </div>
    </header>
    break;
case "FAQ":
    <header>
        <div>
            <nav>
                <ul class="main-menu">
                    <li class="menu-item">Home</li>
                    <li Class="menu-item">Shop</li>
                    <li id="CurPage">FAQ</li>
                    <li class="menu-item">About</li>
                </ul>
            </nav>
        </div>
    </header>
    break;
case "About":
    <header>
        <div>
            <nav>
                <ul class="main-menu">
                    <li class="menu-item">Home</li>
                    <li class="menu-item">Shop</li>
                    <li class="menu-item">FAQ</li>
                    <li id="CurPage">About</li>
                </ul>
            </nav>
        </div>
    </header>
    break;
}

@code {
    string CurrUrl = null;
}
3个回答

10

我使用了

<CascadingValue Name="RouteData" Value="routeData"> ... </CascadingValue>

在 App.Razor 文件中使用级联参数,使当前的路由数据在所有组件中可用。
[CascadingParameter(Name = "RouteData")]
public RouteData? RouteData { get; set; }

RouteData具有一个名为“PageType”的属性,其中包含当前路由的页面组件类型。


暴露RouteData是否有任何缺点?只是好奇,因为他们自己没有暴露它 :) - Jóhann Østerø
在 Blazor 客户端的 AuthorizationHandler 中,有没有访问路由数据的方法? - srivatsa6065
1
这里的缺点是RouteData.PageType仅在Blazor Server上可用,而不适用于WASM :/ 有没有想法如何在客户端版本中获取它? - DanielD

7
您可以从导航管理器中获取当前URL。
@page "/navigate"
@inject NavigationManager NavigationManager

@code {
   string CurrUrl = null;
   protected override void OnInitialized()
   {
       CurrUrl = NavigationManager.Uri.ToString();
   }
}

文档


等一下,这是一个带有 Blazor 组件的 asp.net core Razor 应用程序吗?如果是,那么我不确定如何处理。 - Zsolt Bendes
你不需要使用 ToString(),因为 Uri 已经是一个字符串。 - Fred

6
如何使用 Blazor 组件访问当前路由
这个标题有误导性,应该更改。你不能访问当前路由以完成此任务,因为当前路由尚不存在。
我已经多次搜索了这个问题,并且每个解决方案都没有对我起作用,使用 HttpContext 也没有起作用。
同样地,解决方案不是通过使用当前路由,因为还没有创建路由。你的组件尚未创建,因此没有路由可用。
在 Blazor 中,HttpContext 大多数时候是不可用的,如果有的话...
解决方案:
将以下代码添加到 MainLayout 组件中:
1.定义一个类型为 Type 的属性。该属性将填充将要创建的 Type(组件)。
2.可以从 MainLayout 组件的 OnParametersSet 方法中检索组件的类型。
3.当启动项目时,Type 为 Index。(注意它的格式为: .Pages.Index)
4.如果在浏览器中输入应用程序的 url + "/counter",例如:https://localhost:44373/counter,则会得到 .Pages.Counter。
 @code{

     public Type PageType { get; set; }

     protected override void OnParametersSet()
    {
    
       PageType = (this.Body.Target as RouteView)?.RouteData.PageType;

       Console.WriteLine("This is your type (current type)" + 
                                                      PageType);
    }
  }

在MainLayout.razor文件的顶部,实例化了。请按以下方式向它添加名为PageType的属性参数:
<NavMenu PageType="@PageType" />

左侧的PageType应该在NavMenu组件中定义。正如您所看到的,它绑定到MainLayout中定义的PageType属性。

现在您应该像这样在NavMenu中定义名为PageType的参数属性:

NavMenu.razor

@code {
    [Parameter]
    public Type PageType { get; set; }
} 

现在,您可以在NavMenu组件中使用当前类型(组件),并根据需要使用它。

理解组件如何呈现非常重要...哪个先出现,下一个是什么等等。还有更多...

但是,嘿,您将会在管理任务方面遇到一些困难...以下代码片段非常粗略地演示了您打算执行的工作是可行的(我的代码很好,并且完成了工作,您将遇到的问题与此无关)。

NavMenu.razor

<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
       
    @switch (PageType.ToString())
    {
        case "BlazorApp4.Pages.Index":
            @*<header>
                    <div>
                        <nav>
                            <ul class="main-menu">
                                <li id="CurPage">Home</li>
                                <li class="menu-item">Shop</li>
                                <li class="menu-item">FAQ</li>
                                <li class="menu-item">About</li>
                            </ul>
                        </nav>
                    </div>
                </header>*@

            <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="counter">
                        <span class="oi oi-plus" aria-hidden="true"></span> Counter
                    </NavLink>
                </li>
                <li class="nav-item px-3">
                    <NavLink class="nav-link" href="fetchdata">
                        <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
                    </NavLink>
                </li>
            </ul>
            break;
        case "Shop":
            <header>
                <div>
                    <nav>
                        <ul class="main-menu">
                            <li class="menu-item">Home</li>
                            <li id="CurPage">Shop</li>
                            <li class="menu-item">FAQ</li>
                            <li class="menu-item">About</li>
                        </ul>
                    </nav>
                </div>
            </header>
            break;
        case "FAQ":
            <header>
                <div>
                    <nav>
                        <ul class="main-menu">
                            <li class="menu-item">Home</li>
                            <li Class="menu-item">Shop</li>
                            <li id="CurPage">FAQ</li>
                            <li class="menu-item">About</li>
                        </ul>
                    </nav>
                </div>
            </header>
            break;
        case "About":
            <header>
                <div>
                    <nav>
                        <ul class="main-menu">
                            <li class="menu-item">Home</li>
                            <li class="menu-item">Shop</li>
                            <li class="menu-item">FAQ</li>
                            <li id="CurPage">About</li>
                        </ul>
                    </nav>
                </div>
            </header>
            break;
    }
</div>  

上面的代码将显示默认链接到默认模板页面,当您启动页面时。(首页)。将case "BlazorApp4.Pages.Index:中的代码注释掉,并取消注释位于case "BlazorApp4.Pages.Index":下方的代码(...)。

瞧,全是黑暗...你的痛苦来了...努力工作...祝你好运。


我会听取你的警告,学习组件渲染,并更好地掌握Blazor本身。我还是在学习Blazor方面比较新,我只是一直读到Blazor应该是JavaScript的替代品,并想测试使用Blazor设置活动页面。我不知道这项任务所需的真正工作量,但我喜欢挑战并期待实现我的结果。谢谢! - Recht88
1
Blazor绝对不应该成为JavaScript的替代品...你在哪里读到这个的?在StackOverflow上感谢别人的方式是点赞并接受他们的答案。 - enet
3
除了“这个标题有误导性,你应该改一下”之外,其他都是好答案。当提问时,提问者通常不知道自己不知道什么,因此必须明确自己的意图。这个标题完美地捕捉了意图,并匹配了将带来许多其他人到这个答案的搜索。 - trajekolus

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