-
ABP Framework version: v7.3.0
-
UI Type: Blazor WASM
-
Database System: EF Core (PostgreSQL, etc..)
-
Tiered (for MVC) or Auth Server Separated (for Angular): yes
When I implemented the suggestion for this ticket (https://abp.io/support/questions/7615/Different-Layouts-for-Admin-Pages-vs-Blazor-Application-Pages#answer-3a142526-dea6-14ec-9136-67f84bcec9bd), the application just freezes. If I put a console write statement in the code I see that this method just gets called thousands of times hence why it appears to be frozen.
How can I fix this?
@using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout
@using Volo.Abp.DependencyInjection
@inherits SideMenuLayout
@attribute [ExposeServices(typeof(SideMenuLayout))]
@attribute [Dependency(ReplaceServices = true)]
@Body
@code
{
[Inject] private NavigationManager _navManager { get; set; }
private Type GetLayout()
{
var currentUrl = _navManager.Uri;
//Console.WriteLine($"***** CURRENT URL: {currentUrl} *****");
// if (currentUrl == "xxx")
//{
// return typeof(AdminLayout);
// }else if (currentUrl == xxxx)
// {
// return typeof(ApplicationLayout);
// }
return typeof(SideMenuLayout);
}
}
5 Answer(s)
-
0
Hi there,
I can share the following implementation suggestion to you.
Let's say we have
LayoutA.razor
,LayoutB.razor
and aMyCustomLayout.razor
file that manages the current layoutLayoutA.razor
@inherits LayoutComponentBase <div class="layout-container"> <div class="layout-sidebar"> <div class="layout-sidebar-header"> <h1>Layout A</h1> </div> </div> <div class="layout-content"> @Body </div> </div>
LayoutB.razor
@inherits LayoutComponentBase <div class="layout-container"> <div class="layout-sidebar"> <div class="layout-sidebar-header"> <h1>Layout B</h1> </div> </div> <div class="layout-content"> @Body </div> </div>
MyCustomLayout.razor
@using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout @inherits LayoutComponentBase @implements IDisposable @inject NavigationManager NavigationManager <LayoutView Layout="@CurrentLayout"> @Body </LayoutView> @code { public Type CurrentLayout { get; set; } = typeof(SideMenuLayout); protected override Task OnInitializedAsync() { NavigationManager.LocationChanged += OnLocationChanged; SetLayout(NavigationManager.Uri); return base.OnInitializedAsync(); } public void Dispose() { NavigationManager.LocationChanged -= OnLocationChanged; } private void OnLocationChanged(object sender, LocationChangedEventArgs e) { SetLayout(e.Location); } private void SetLayout(string location) { if (location.Contains("page-a")) { CurrentLayout = typeof(LayoutA); } else if (location.Contains("page-b")) { CurrentLayout = typeof(LayoutB); } else { CurrentLayout = typeof(SideMenuLayout); } StateHasChanged(); } }
And create two components with path
/page-a
and/page-b
PageA.razor
@page "/page-a" <h3>PageA</h3> <p> This is PageA. </p>
PageB.razor
@page "/page-b" <h3>PageA</h3> <p> This is PageA. </p>
Then configure it to make it work with LeptonX theme as a default layout:
Configure<LeptonXThemeBlazorOptions>(options => { options.Layout = typeof(MyCustomLayout); });
-
0
Ok. Thank you! That solution worked as how I needed.
-
0
Ok. Thank you! That solution worked as how I needed.
-
0
Ok, so now it appears all the pages that still use the standard ABP SideMenuLayout layout are not adding the MainHeaderToolbarUserMenu component to upper right corner of the page.
Here is my code
DynamicLayoutPicker.razor
@inherits LayoutComponentBase @Body
DynamicLayoutPicker.razor.cs
using CFDataSystems.StructureCloud.Blazor.Themes.LeptonX.Layouts.TenantLayout; using CFDataSystems.StructureCloud.Components.Layouts; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Routing; using System.Threading.Tasks; using System; using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout; namespace CFDataSystems.StructureCloud.Blazor.Themes.LeptonX.Layouts; public partial class DynamicLayoutPicker : LayoutComponentBase, IDisposable { [Inject] private NavigationManager _navManager { get; set; } public Type CurrentLayout { get; set; } = typeof(SideMenuLayout); protected override Task OnInitializedAsync() { _navManager.LocationChanged += OnLocationChanged; SetLayout(_navManager.Uri); return base.OnInitializedAsync(); } public void Dispose() { _navManager.LocationChanged -= OnLocationChanged; } private void OnLocationChanged(object sender, LocationChangedEventArgs e) { SetLayout(e.Location); } private void SetLayout(string location) { Console.WriteLine($"***** CURRENT URL: {location} *****"); if (location.Contains("tenant-procedure-list")) { CurrentLayout = typeof(ProceduresPageLayout); Console.WriteLine($"***** CURRENT Layout: ProceduresPageLayout *****"); } else if (location.Contains("SampleTenantDefault")) { CurrentLayout = typeof(TenantDefaultLayout); Console.WriteLine($"***** CURRENT Layout: TenantDefaultLayout *****"); } else { CurrentLayout = typeof(SideMenuLayout); Console.WriteLine($"***** CURRENT Layout: SideMenuLayout *****"); } StateHasChanged(); } }
BlazorModule.cs
Configure(options => { //options.Layout = LeptonXBlazorLayouts.SideMenu; options.Layout = typeof(DynamicLayoutPicker); });
<br>
<br>
<br>
<br>
<br>
<br>
<br> -
0
Hi,
So you can disregard this last comment as I tracked down the logic and see that I needed to create my own ToolbarContributor that specificaly look at the LeptonXThemeBlazorOptions and factor in my DynamicLayoutPicker in order to add the SideMenuUserMenu component to the ToolBar.Items collection.
public class StructureToolbarContributor : IToolbarContributor { public Task ConfigureToolbarAsync(IToolbarConfigurationContext context) { if (context.Toolbar.Name == StandardToolbars.Main) { var options = context.ServiceProvider.GetRequiredService>().Value; if (options.Layout == typeof(DynamicLayoutPicker)) { context.Toolbar.Items.Add(new ToolbarItem(typeof(SideMenuUserMenu))); } } return Task.CompletedTask; } } Changes to the Blazor ABP Module class Configure(options => { options.Contributors.Add(new LeptonXThemeToolbarContributor()); options.Contributors.Add(new StructureToolbarContributor()); //options.Contributors.Add(new MessageToolBarContributor()); });
Thanks