【问题标题】:Blazor How to get a Blazor component to not reload/re-renderBlazor 如何让 Blazor 组件不重新加载/重新渲染
【发布时间】:2021-11-21 17:13:06
【问题描述】:

我正在 Blazor 中构建动态下拉导航栏。现在的问题是,当分页发生时,导航栏组件会重新加载并且下拉菜单会消失(这不是我想要的)。

我知道这是真的,因为当我将 navigationManager.NavigateTo(route); 排除在等式之外时,它会按预期工作。

我的主布局:

<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);
    }

*抱歉缩进不好。

那么有没有办法让 NavigationMenu.razor 组件在我调用 navigationManager.NavigateTo(route); 时不呈现或重新加载它的状态?

【问题讨论】:

  • 这就是导航的本质——加载一个页面,这涉及到重置它的变量。如果你想在导航中保持状态,你需要一些方法来保存那个状态。一种方法是使用范围服务。

标签: c# blazor


【解决方案1】:

为避免组件自动重新加载,您应该重写 ShouldRender 方法,并使其始终返回 false。

但是,您应该检查生成的 HTML。您正在导航的页面似乎没有继承 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>

页面包含的任何部分,即使您在 ShouldRender 中返回 false。

NavigationMenu 组件中的状态更改不应使其消失。

【讨论】:

  • 我发现了问题。我忘了声明我的页面使用 MainLayout 的布局,所以整个应用程序页面而不是只有那些页面。所以我在所有页面中添加了“@layout MainLayout”
【解决方案2】:

NavigateTo(route) 重新加载由“路由”地址指定的整个页面。 布局是在页面级别指定的。当您导航到某个地址时,布局会再次初始化并重置其 UI 状态。这意味着您的所有下拉扩展、格式更改等都将丢失。例如,在您的情况下,以下 CSS 分配丢失:

subButton.StyleClassString = ButtonActiveStyle.normal;

subButton(s) 的 StyleClassString 成员将被重置为初始值(是否为空?)

因此,确保下拉菜单保持其状态的唯一方法是将其存储在某个地方。 您可以通过两种方式实现它:

  1. Read it from the current URL
  2. 将其作为状态存储在内存中的某处并在 OnInitialized 中读取(复杂,我不会真正推荐)

【讨论】:

  • 我已将它存储在一个类中的 .cs 文件中,并且 subButton.StyleClassString 工作正常,但问题仍然存在,有时当我单击它时它会消失。所以我只是不希望组件重新加载或重新渲染。
猜你喜欢
  • 1970-01-01
  • 2019-11-12
  • 2022-01-19
  • 2020-12-25
  • 2020-02-13
  • 2022-01-16
  • 2020-11-27
  • 2022-08-21
  • 2020-02-15
相关资源
最近更新 更多