简体   繁体   中英

Blazor How to get a Blazor component to not reload/re-render

I am building a dynamic Drop Down Navigation bar in Blazor. Now the problem is that when paging occurs the Navbar component reloads and the drop down dissapears (which is not what I want).

I know this is true because when I take the navigationManager.NavigateTo(route); out of the equation then it works as intended.

My MainLayout:

<div style="height: 100%; width: 100%; display: flex;">
    <div style="height: 100%; width: 170px">
        <NavigationMenu></NavigationMenu>
    </div>

    <div class="flex-child-expand">
        @Body
    </div>
</div>

NavigationMenu.razor

<div>
            @foreach (var navButton in NavManager.MainNavButtons)
            {
                <div class="dropdown">
                    <button class="@navButton.StyleClassString" @onclick="@(() => OnButtonClicked(navButton, navButton.ButtonRoute))">@navButton.ButtonString</button>
                    <div class="dropdown-content">
                        @foreach (var button in navButton.SubSection)
                        {
                            <button class="@button.StyleClassString" @onclick="@(() => OnButtonClicked(navButton, button.ButtonRoute, button.ButtonString))">@button.ButtonString</button>
                        }
                    </div>
                </div>
            }

        </div>

 private void OnButtonClicked(NavManager.NavButton mainButtonPressed, string route, string buttonString = "")
    {
        if(buttonString == "")
        {
            foreach (var mainbtn in NavManager.MainNavButtons)
            {
                if (mainbtn.Section == mainButtonPressed.Section)
                {
                    mainbtn.StyleClassString = ButtonActiveStyle.active;
                }
                else
                {
                    mainbtn.StyleClassString = ButtonActiveStyle.normal;
                }

                //cleanup
                foreach (var subButton in mainbtn.SubSection)
                {
                    subButton.StyleClassString = ButtonActiveStyle.normal;
                }
            }

            if(mainButtonPressed.SubSection.Count > 0)
            {
                mainButtonPressed.SubSection[0].StyleClassString = ButtonActiveStyle.active;
            }

        }
        else
        {
            foreach (var mainbtn in NavManager.MainNavButtons)
            {
                if (mainbtn.Section == mainButtonPressed.Section)
                {
                    mainbtn.StyleClassString = ButtonActiveStyle.active;
                }
                else
                {
                    mainbtn.StyleClassString = ButtonActiveStyle.normal;
                }


                foreach (var subButton in mainbtn.SubSection)
                {
                    if (subButton.ButtonString == buttonString)
                    {
                        subButton.StyleClassString = ButtonActiveStyle.active;
                    }
                    else
                    {
                        subButton.StyleClassString = ButtonActiveStyle.normal;
                    }
                }
            }

        }

        GoToPage(route);

    }

    private void GoToPage(string route)
    {
        navigationManager.NavigateTo(route);
    }

*Sorry for bad indentation.

So is there a way to make the NavigationMenu.razor component from not rendering or reloading it's state when I call navigationManager.NavigateTo(route); ?

To avoid a component to auto reload, you should override the ShouldRender method, and make it always return false.

However, you should check your resulting HTML. It seems that the page that you are navigating into does not inherit MainLayout.

This means that it will overwrite the

<div style="height: 100%; width: 100%; display: flex;">
    <div style="height: 100%; width: 170px">
        <NavigationMenu></NavigationMenu>
    </div>

    <div class="flex-child-expand">
        @Body
    </div>
</div>

portion for whatever the page contains, even if you return false in the ShouldRender.

A state change in the NavigationMenu component should not make it disappear.

NavigateTo(route) loads an entire page afresh specified by the 'route' address. Layouts are specified at a page level. When you navigate to an address, the layout is initialized again and its UI state is reset. This means that all your dropdown expansions, formatting changes etc are lost. For example, in your case, the following CSS assignment is lost:

subButton.StyleClassString = ButtonActiveStyle.normal;

StyleClassString members of subButton(s) will be reset to the initial value (is it null?)

Therefore, the only way you can make sure that the dropdown persists its state, is if you store it somewhere. You can achieve it in two ways:

  1. Read it from the current URL
  2. Store it as a state somewhere in the memory and read it in OnInitialized (complex and I won't really recommend)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM