Home > Software engineering >  Restore NavMenu item when clicking it
Restore NavMenu item when clicking it

Time:10-01

I have a list being shown on a page that is filtered by a bool parameter that I'm using to pass to a component:

ProjectList.razor:

@if (IsDetail == true)
{
    <ProjectDetail OnDetailShown="UpdateDetailView"></ProjectDetail>
}
else
{
    <a  @onclick="() => OnClick(projectId)"  @onclick:preventDefault>DETAILS</a>
}
@code
{
    public bool IsDetail { get; set; }

    private void UpdateDetailView()
    {
        IsDetail = false;
    }

    private void OnClick(int projectId)
    {
        IsDetail = true;
        Project = Projects.First(x => x.ProjectId == projectId);
    }
}

and my component ProjectDetail:

<h3>Project Details</h3>

<button  @onclick="OnClick">Save</button>

@code {
    [Parameter]
    public bool IsDetail { get; set; }

    private void OnClick()
    {
        OnDetailShown.InvokeAsync(false);
    }
}

the idea here is that when user clicks on the button "DETAILS" in the list of projects, the onClick sets the "isDetail" to true and this hides the entire list and shows the detail via the ProjectDetail component. and from the component, when clicking "save" sends back the "isDetail" as false, so it shows the list again and hides the details.

this right now is working. however my small issue is that when clicking the navigation navbar on the left, if I click the "Project list" link when the details are being shown, the isDetail being "true" doesn't make visible the entire list.

How can I do so that when the user clicks also the "project list" button on the navigation:

<div >
        <NavLink  href="projectList">
            <span  aria-hidden="true"></span> Project List
        </NavLink>
    </div>

the isDetail is changed to false so it shows the list again and hide the details?

CodePudding user response:

This behavior is by design. Clicking on the menu item does not cause the ProjectList component to be re-rendered because the url did not change, and no parameters have changed. Of course you can solve it by creating a similar component based on the NavLink component. Start here:

The following solution is somewhat sort of a workaround, but it works.

Change

<NavLink  href="projectlist">
    <span  aria-hidden="true"></span> Home
</NavLink>

To:

<NavLink  href="@($"projectlist/{value}")" >
            <span  aria-hidden="true"></span> Home
</NavLink>

@code {
    // Add a boolean value which is toggled, effectively constantly 
    // changing the url, and thus when you click on the link the
    // ProjectList component always re-render 
    private bool value = true;
    private bool collapseNavMenu = true;
   

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

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

ProjectList.razor

@page "/projectlist"
@page "/{ShouldClose:bool}"
<div>project list: Hello world</div>

@if (IsDetail == true)
{
    IsDetail = false;
    <FetchData Close="CloseDetail" />
}
else
{
    <div>List here</div>
    <a  @onclick="() => OnClick(12)">DETAILS</a>
}
@code
{
    [Parameter]
    public bool ShouldClose { get; set; }
    public bool IsDetail { get; set; } = false;

    private void CloseDetail()
    {
        IsDetail = false;
    }

    private void OnClick(int projectId)
    {
        IsDetail = true;
        
        // Project = Projects.First(x => x.ProjectId == projectId);
    }
       
}

Add this at the bottom of FetchData.razor:

<button type="button" @onclick="@(() => Close.InvokeAsync())">Close 
   me</button>

And the @code block should look like this, provided you're using Blazor Server App:

@code {
    private WeatherForecast[] forecasts;

    [Parameter]
    public EventCallback Close { get; set; }

    protected override async Task OnInitializedAsync()
    { 

        forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
    }
}
  • Related