I've referenced my code from Here and have a follow up
Attempting to access changed infomation in MainLayout based on changes in the @body
Mainlayout with NavPathComponent
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<NavPathComponent />
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
</div>
<article class="content px-4">
@Body
</article>
<footer style="background-color:#3a0647; position: fixed;bottom: 0; width: -webkit-fill-available; padding:5px;">
<div class="logo-footer">
<a href="https://bhinc.com/" target="_blank">
<img src="Images/bh-logo-light.svg" />
</a>
</div>
</footer>
</main>
</div>
My component.razor with what I want to update based on @vody changes
@inject NavigablePathService NavigablePath
@implements IDisposable
<h3>NavPathComponent</h3>
<div class="col top-row px-4">
<p>
@if (NavigablePath.NavigablePath != null)
{
@foreach (string folder in NavigablePath.NavigablePath.Split("\\"))
{
<label style="cursor: pointer;color:blue;">@(folder)</label>
<label> > </label>
}
}
</p>
</div>
@code {
public Func<Task> NavPathChange { get; set; }
protected override void OnInitialized()
{
NavPathChange = async () =>
{
await InvokeAsync(StateHasChanged);
};
NavigablePath.NavigablePathSelector += NavPathChange;
}
public void Dispose()
{
NavigablePath.NavigablePathSelector -= NavPathChange;
}
}
My service.cs
public class NavigablePathService
{
public string NavigablePath { get; set; }
public Func<Task> NavigablePathSelector { get; set; }
public async Task ChangePath(string newPath)
{
NavigablePath = newPath;
await NavigablePathSelector.Invoke();
}
}
The issue I run into is that Func is null when I call it from my OnIntialize in my @page
protected override void OnInitialized()
{
navigablePathService.ChangePath("test\\banana");
}
First is this the right practive I attempted Casacading Value nesting a this Value="this" in MainLayout that didn't make much sense to me.
Would adding a constructor to my service and injecting it with a Func be a thing?
public NavigablePathService(Func<Task> navigablePathSelector)
{
NavigablePathSelector = navigablePathSelector;
}
You could try this code:
MainLayout.razor:
@inherits LayoutComponentBase
<PageTitle>NavPathApp</PageTitle>
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<NavPathComponent />
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</div>
<article class="content px-4">
@Body
</article>
</main>
</div>
NavPathComponent.razor:
@inject NavPathApp.Services.NavigablePathService NavigablePath
@implements IDisposable
<h3>NavPathComponent</h3>
<div class="col top-row px-4">
<p>
@if (NavigablePath.NavigablePath != null)
{
@foreach (string folder in NavigablePath.NavigablePath.Split("\\"))
{
<label style="cursor: pointer; color: blue;">@(folder)</label>
<label> > </label>
}
}
</p>
</div>
@code {
protected override void OnInitialized()
{
// Console.WriteLine("NavPathComponent: Subscribing to OnNavigablePathChanged event...");
NavigablePath.OnNavigablePathChanged += UpdateNavPath;
}
private async Task UpdateNavPath()
{
//Console.WriteLine("NavPathComponent: Event triggered, updating state...");
await InvokeAsync(StateHasChanged);
}
public void Dispose()
{
//Console.WriteLine("NavPathComponent: Unsubscribing from OnNavigablePathChanged event...");
NavigablePath.OnNavigablePathChanged -= UpdateNavPath;
}
}
NavigablePathService.cs:
using System;
using System.Threading.Tasks;
namespace NavPathApp.Services
{
public class NavigablePathService
{
public string NavigablePath { get; set; }
public event Func<Task> OnNavigablePathChanged;
public async Task ChangePath(string newPath)
{
NavigablePath = newPath;
// Console.WriteLine($"Path changed to: {NavigablePath}");
if (OnNavigablePathChanged != null)
{
// Console.WriteLine("Invoking OnNavigablePathChanged event...");
await OnNavigablePathChanged.Invoke();
}
}
}
}
TestPage.razor:
@page "/test"
@inject NavPathApp.Services.NavigablePathService navigablePathService
<h3>Test Page</h3>
<button @onclick="ChangePath">Change Path</button>
@code {
private async Task ChangePath()
{
// Console.WriteLine("TestPage: Changing path to test\\banana...");
await navigablePathService.ChangePath("test\\banana");
}
protected override async Task OnInitializedAsync()
{
// Console.WriteLine("TestPage: Initializing and setting path to initial\\path...");
// Initial path setup if needed
await navigablePathService.ChangePath("initial\\path");
}
}
Program.cs:
builder.Services.AddSingleton<NavigablePathService>();
Result: