c# - 在 Blazor 中的 Page 和 NavMenu 之间交换数据

标签 c# blazor razor-pages blazor-server-side

我有一个标准的 blazor 项目,它具有以下组件:

-> MainLayout.razor
-> NavMenu.razor
-> Pages/Index.razor
-> Pages/Sub1.razor

MainLayout 如下所示:
<div class="sidebar">
    <NavMenu />
</div>
<div>@Body</div>

现在我想在我的页面(index.razor,sub1.razor)和导航菜单之间交换数据,所以我可以在导航菜单中添加类似这样的内容:
<div><p>You are now on Page: @CurrentPageName</p></div>

如何直接从我的页面中设置 (navMenu).CurrentPageName?我希望为此使用静态类并不是一个好的选择。

最佳答案

更好的范围服务实现:

 public class CurrentPage
    {
        public string CurrentPageName { get; private set; }

        public void SetCurrentPageName(string name)
        {
            if (!string.Equals(CurrentPageName, name)) 
            {
                CurrentPageName = name;
                NotifyStateChanged();
            }
        }

        public event Action OnChange; // event raised when changed

        private void NotifyStateChanged() => OnChange?.Invoke();
    }

我们不是在传递对象的字典,我们有一个做一件事的简单服务。更改页面的唯一方法是调用 SetCurrentPageName ,这会引发一个事件,让消费者知道名称已更改。这在非嵌套组件之间是必需的,因为否则更新不会传播。

我们还需要在启动时注册服务(因为当前页面是特定于 session 的):
            services.AddScoped<CurrentPage>();

我们将注入(inject) Index.razor ,并使用它:
@page "/"
@inject CurrentPage currentPage

<h1>Hello, world!</h1>

Welcome to your new app.
<button @onclick="ChangeName">Set Page Name</button>

<SurveyPrompt Title="How is Blazor working for you?" />
@code
{

    protected override void OnInitialized()
    {
        currentPage.SetCurrentPageName("The Home Page");
        base.OnInitialized();
    }

    void ChangeName() => currentPage.SetCurrentPageName("Name changed");
}

最后在 NavMenu.razor 的顶部:
@inject CurrentPage currentPage

再往下..

    <p>The current page is @currentPage.CurrentPageName</p>

@code {
    protected override void OnInitialized()
    {
        // if the OnChange event is raised, refresh this view
        currentPage.OnChange += () => StateHasChanged();

        base.OnInitialized();
    }

这个状态类对它的使用方式一无所知,也没有传递任何对象或引用。

[编辑] 我决定用于设置页面名称的注入(inject)/覆盖模式相当 unBlazor,所以我还编写了一个组件来简化它 - PageName.razor:
@inject CurrentPage currentPage;

@code {
    [Parameter]
    public string Name { get; set; }

    protected override void OnParametersSet()
    {
        currentPage.SetCurrentPageName(Name);
    }
}

现在任何想要设置标题的页面都可以这样做:
@page "/fetchdata"
@inject HttpClient Http
<PageName Name="Weather forecast page!" />

整个消费者现在是一个组件:)

关于c# - 在 Blazor 中的 Page 和 NavMenu 之间交换数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60912726/

相关文章:

visual-studio - 在 Razor Pages 中显示字符串数组?

c# - _bstr_r 与 _T ("")

c# - Xamarin Forms 最佳行为和验证

c#,要处理的面板中的控件

C# Blazor - 如何限制文本框的 onChange 事件

asp.net-core-2.0 - 自定义网址重写

asp.net-core - 检查是否向 Razor 页面发出请求

c# - Visual Studio Selenium 测试启动本地项目

dependency-injection - 将组件的依赖注入(inject)方法移动到 Blazor 服务器端中的单独 CS 库

blazor - 如何使用 Blazor 服务器端判断用户何时离开站点