Blazor-是否可以从MainLayout触发页面组件中的功能

时间:2020-07-17 15:43:28

标签: blazor blazor-server-side

我的MainLayout.razor组件中有一个侧边抽屉,用于设置/更改某些值,然后在整个应用程序中使用。

<CascadingValue Value="@appValues" Name="AppValue">
    <SideDrawer OnUpdate="@RefreshPage"></SideDrawer>
    <div class="content px-4">
        @Body
    </div>
</CascadingValue>

当我更新SideDrawer中的值时,我执行了EventCallback,通过它我可以更新变量,然后这些变量可以用作整个页面组件中的级联值。

@code{
    public AppValues appValues = new AppValues();
    protected void RefreshPage()
    {
        appValues.value1 = somevaluefromsidedrawer;
        appValues.value2 = someothervaluefromsidedrawer;
        StateHasChanged();
    }
}

这些层叠值在页面组件中更新得很好。但是问题是,在页面组件中,有一种方法(比如LoadData()),其中某些数据集应基于这些级联值进行更新。

@code{
    [CascadingParameter(Name = "AppValue")]
    protected AppValues appValues { get; set; }
    protected void RefreshCurrentPage()
    {
        LoadData(appValues.value1);
    }
}

理想情况下,我希望能够从RefreshCurrentPage()组件中的RefreshPage()方法调用页面组件中的MainLayout.razor方法,以便该页面组件中的所有数据集将根据更新后的值刷新。

有可能做这样的事情吗?

1 个答案:

答案 0 :(得分:1)

您可以通过多种方式做到这一点:

您可以将对MainLayout组件的引用以CascadingValue vomponent的形式传递给感兴趣的子组件,如下所示:

<CascadingValue Value="this" Name="TheMainLayout">
    
</CascadingValue>

子组件应该像这样获取引用:

@code{
    [CascadingParameter(Name = "TheMainLayout")]
    public MainLayout MainLayout { get; set; }
    
}

并将其自身添加到MainLayout组件中定义的组件列表中:

 // Child component adds itself to the  MainLayout component
    protected override void OnInitialized()
    {
        MainLayout.AddPage(this);
    }

在MainLayout组件中,您将定义ComponentBase对象的列表, 和AddPage方法如下:

public void AddPage(ComponentBase page)
{
    // Code to add the page component to the list
}

现在MainLayout拥有对组件的引用,它可以直接调用在每个添加的页面组件中定义的RefreshCurrentPage(我猜它只能是一个,因为我们在谈论可路由组件,对)。

注意:以上仅是解决方案的概述。您可以扩展它以提供每次需要刷新数据时引发的事件,并且每个页面组件都应订阅该事件,当引发该事件时,调用RefreshCurrentPage方法。与直接从MainLayout调用RefreshCurrentPage相比,这是一种更好,更复杂的方法。

您应提供代码,以在组件列表被杀死等时从组件列表中删除添加的组件引用。

请注意,不再需要appValues的CascadingValue,因为子组件拥有对MainLayout的引用,并且可以直接访问这些值。

注意:可以通过将服务类注入MainLayout组件及其子级来实现上述所有过程。

好久不见...