admin管理员组文章数量:1418302
Is it possible to do something like this:
<Router AppAssembly="@typeof(Routes).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" Path="/admin/*" DefaultLayout="@typeof(AdminLayout)" />
<RouteView RouteData="@routeData" Path="/user/*" DefaultLayout="@typeof(UserLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1"/>
</Found>
</Router>
I've found this question: Change layout in Blazor page based on URL
But it doesn't quite do what I want with multiple layout files. Thanks.
Is it possible to do something like this:
<Router AppAssembly="@typeof(Routes).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" Path="/admin/*" DefaultLayout="@typeof(AdminLayout)" />
<RouteView RouteData="@routeData" Path="/user/*" DefaultLayout="@typeof(UserLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1"/>
</Found>
</Router>
I've found this question: Change layout in Blazor page based on URL
But it doesn't quite do what I want with multiple layout files. Thanks.
Share Improve this question asked Jan 29 at 16:30 Jon BarkerJon Barker 1,82817 silver badges25 bronze badges3 Answers
Reset to default 2The easiest way is to set your layout in the _imports.razor
file:
Simply structure your pages in folders:
Pages
- Folder1
- _imports.razor <= add the line
@layout Folder1Layout
- Page11.razor
- Page12.razor
- _imports.razor <= add the line
- Folder2
- _imports.razor <= add the line
@layout Folder2Layout
- Page21.razor
- Page22.razor
- Folder21
- _imports.razor <= add the line
@layout Folder21Layout
- Page211.razor
- _imports.razor <= add the line
- _imports.razor <= add the line
- Folder1
Layouts
- Folder1Layout.razor
- Folder2Layout.razor
- Folder21Layout.razor
You can add also any attributes you want in the _imports.razor to apply them to the pages in the same folder. For example for pages to manage user account, you want the user with authorizations:
@layout ManageLayout
@attribute [Microsoft.AspNetCore.Authorization.Authorize]
In your case, Folder1 can be admin
and Folder2 user
Something like this. You can use pattern matching if you have multiple options, and be more precise with the Uri match if you wish.
@inject NavigationManager NavigationManager
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="routeData" DefaultLayout="_defaultLayout" />
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>
@code {
private Type _defaultLayout =>
this.NavigationManager.Uri.Contains("admin")
? typeof(Layout.AdminLayout)
: typeof(Layout.MainLayout);
}
This is what I came up with before anyone else responded. See the other answers for a simpler approach.
Routes.razor
<Router AppAssembly="@typeof(Routes).Assembly">
<Found Context="routeData">
<ReSolverRouteLayout @ref=resolverRouteLayout
RouteData="@routeData"
DefaultLayout="@typeof(MainLayout)"
InitializeMappings="InitializeMappings" />
<FocusOnNavigate RouteData="@routeData" Selector="h1"/>
</Found>
</Router>
@code
{
private ReSolverRouteLayout resolverRouteLayout = null!;
private void InitializeMappings()
{
resolverRouteLayout.AddRouteLayoutMapping("/console/", typeof(ConsoleLayout));
resolverRouteLayout.AddRouteLayoutMapping("/program/", typeof(ProgramLayout));
}
}
ReSolverRouteLayout.cs
public class ReSolverRouteLayout : RouteView
{
private Dictionary<string, Type> routePrefixLayoutLookup = new();
[Inject]
public required NavigationManager NavigationManager { get; set; }
[Parameter]
public required Action InitializeMappings { get; set; }
/// <summary>
/// Adds a route/layout mapping (called by children)
/// </summary>
public void AddRouteLayoutMapping(string routePrefix, Type layout)
{
routePrefixLayoutLookup[routePrefix] = layout;
}
/// <summary>
/// Renders the layout/body. Stolen from RouteView
/// </summary>
protected override void Render(RenderTreeBuilder builder)
{
InitializeMappings();
var pageLayoutType = GetLayoutTypeForRouteOrDefault();
builder.OpenComponent<LayoutView>(0);
builder.AddComponentParameter(1, nameof(LayoutView.Layout), pageLayoutType);
builder.AddComponentParameter(2, nameof(LayoutView.ChildContent), (RenderFragment)RenderPageWithParameters);
builder.CloseComponent();
}
/// <summary>
/// Looks up the defined mappings and attempts to find a relevant layout.
/// </summary>
/// <returns></returns>
private Type GetLayoutTypeForRouteOrDefault()
{
var match = routePrefixLayoutLookup.SingleOrDefault(each => NavigationManager.Uri.Contains(each.Key)).Value;
if(match != null)
return match;
return DefaultLayout;
}
/// <summary>
/// Stolen from base class.
/// </summary>
private void RenderPageWithParameters(RenderTreeBuilder builder)
{
builder.OpenComponent(0, RouteData.PageType);
foreach (var kvp in RouteData.RouteValues)
{
builder.AddComponentParameter(1, kvp.Key, kvp.Value);
}
builder.CloseComponent();
}
}
本文标签: cBlazor Determine Layout based upon RouteStack Overflow
版权声明:本文标题:c# - Blazor: Determine Layout based upon Route - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745290198a2651746.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论