Blazor:如何将值从一个组件发送到另一个组件?

Blazor:如何将值从一个组件发送到另一个组件?,blazor,Blazor,我有两个组件:标题.razor和内容.razor。通过选择不同的菜单选项,可以更改内容。随着每次内容的更改,我需要将内容相关的值发送到标题。我尝试了不同的技术,但结果相同,标题中的值不会得到更新。我还有别的事要做吗?我的代码: 收割台。剃须刀: <div>Content Name: @ContentName</div> @code { [Parameter] public string ContentName{ get; s

我有两个组件:标题.razor内容.razor。通过选择不同的菜单选项,可以更改内容。随着每次内容的更改,我需要将内容相关的发送到标题。我尝试了不同的技术,但结果相同,标题中的值不会得到更新。我还有别的事要做吗?我的代码:

收割台。剃须刀

    <div>Content Name: @ContentName</div>
    @code {
        [Parameter]
        public string ContentName{ get; set; }
    }
@code{
    [CascadingParameter]
    MainLayout Parent { get; set; }

    protected override void OnInitialized()
        {
            base.OnInitialized();
            ContentName = "Content 1";
            Parent.SetParameters(ContentName);
        }
}

@inherits LayoutComponentBase
@inject BlazorQART.Data.AppState AState
<div class="sidebar" >
    <NavMenu />
</div>

<div class="main">
    <div class="top-row px-4">
        <Header ContentName="@_ContentName" />
    </div>
    <div class="content px-4">
        <CascadingValue Value="@this">
            @Body
        </CascadingValue>
    </div>
</div>
@code{
    private string _ContentName{ get; set; }
    protected override void OnInitialized()
    {
        base.OnInitialized();
        AState.OnContentChange = OnContentChanged;
    }
    public void SetParameters (string content)
    {
        AState.ChangedContent = content;
    }
    protected async void OnContentChanged(string content)
    {
        await InvokeAsync(() =>
        {
            _ContentName = content;
        });
    }
    public class AppState
    {
        private string _ChangedContent;
        public Action<string> OnContentChange { get; set; }
        public string ChangedContent
        {
            get { return _ChangedContent; }
            set
            {
                _ChangedContent= value;
                OnContentChange.Invoke(_ChangedContent);
            }
        }
    }

主布局。剃须刀

    <div>Content Name: @ContentName</div>
    @code {
        [Parameter]
        public string ContentName{ get; set; }
    }
@code{
    [CascadingParameter]
    MainLayout Parent { get; set; }

    protected override void OnInitialized()
        {
            base.OnInitialized();
            ContentName = "Content 1";
            Parent.SetParameters(ContentName);
        }
}

@inherits LayoutComponentBase
@inject BlazorQART.Data.AppState AState
<div class="sidebar" >
    <NavMenu />
</div>

<div class="main">
    <div class="top-row px-4">
        <Header ContentName="@_ContentName" />
    </div>
    <div class="content px-4">
        <CascadingValue Value="@this">
            @Body
        </CascadingValue>
    </div>
</div>
@code{
    private string _ContentName{ get; set; }
    protected override void OnInitialized()
    {
        base.OnInitialized();
        AState.OnContentChange = OnContentChanged;
    }
    public void SetParameters (string content)
    {
        AState.ChangedContent = content;
    }
    protected async void OnContentChanged(string content)
    {
        await InvokeAsync(() =>
        {
            _ContentName = content;
        });
    }
    public class AppState
    {
        private string _ChangedContent;
        public Action<string> OnContentChange { get; set; }
        public string ChangedContent
        {
            get { return _ChangedContent; }
            set
            {
                _ChangedContent= value;
                OnContentChange.Invoke(_ChangedContent);
            }
        }
    }

@继承LayoutComponentBase
@注入BlazorQART.Data.AppState AState
@身体
@代码{
私有字符串_ContentName{get;set;}
受保护的覆盖无效OnInitialized()
{
base.OnInitialized();
AState.OnContentChange=OnContentChanged;
}
公共void SetParameters(字符串内容)
{
AState.ChangedContent=内容;
}
受保护的异步void OnContentChanged(字符串内容)
{
等待调用同步(()=>
{
_ContentName=内容;
});
}
AppState.cs

    <div>Content Name: @ContentName</div>
    @code {
        [Parameter]
        public string ContentName{ get; set; }
    }
@code{
    [CascadingParameter]
    MainLayout Parent { get; set; }

    protected override void OnInitialized()
        {
            base.OnInitialized();
            ContentName = "Content 1";
            Parent.SetParameters(ContentName);
        }
}

@inherits LayoutComponentBase
@inject BlazorQART.Data.AppState AState
<div class="sidebar" >
    <NavMenu />
</div>

<div class="main">
    <div class="top-row px-4">
        <Header ContentName="@_ContentName" />
    </div>
    <div class="content px-4">
        <CascadingValue Value="@this">
            @Body
        </CascadingValue>
    </div>
</div>
@code{
    private string _ContentName{ get; set; }
    protected override void OnInitialized()
    {
        base.OnInitialized();
        AState.OnContentChange = OnContentChanged;
    }
    public void SetParameters (string content)
    {
        AState.ChangedContent = content;
    }
    protected async void OnContentChanged(string content)
    {
        await InvokeAsync(() =>
        {
            _ContentName = content;
        });
    }
    public class AppState
    {
        private string _ChangedContent;
        public Action<string> OnContentChange { get; set; }
        public string ChangedContent
        {
            get { return _ChangedContent; }
            set
            {
                _ChangedContent= value;
                OnContentChange.Invoke(_ChangedContent);
            }
        }
    }

公共类AppState
{
私有字符串_ChangedContent;
内容更改{get;set;}的公共操作
公共字符串更改内容
{
获取{return\u ChangedContent;}
设置
{
_更改内容=值;
OnContentChange.Invoke(_ChangedContent);
}
}
}

您可以使用多种方法来解决此问题,我将分享其中的一些方法

第一个选项是使用外部组件处理内容的状态和传入参数,以及
EventCallBack
方法。在大多数情况下,Blazor引擎应自行获取更改并重新渲染

第二个选项更为复杂,包括使用注入服务作为状态容器和事件中心,并订阅每个组件中的事件以收集数据。关于如何实现这一点的讨论,我建议深入阅读前面提到的关于Blazor DI生命周期的文章,并确保您理解它们,但一旦您这样做,您就可以设置作用域服务或临时服务以仅支持您所在的页面。此选项讨论跨连接更新组件,但以相同的方式使用该服务也适用于同一页面上的不同组件。对于您的情况来说,这可能有些过分,但这是一个很好的工具

关于级联参数的简要说明:我看到上面列出了一个,这个特性有它的用途,但它也耦合了捕获
[CascadingParameter]的任何组件提供参数的组件的
属性,因为组件的某些功能将取决于该级联参数。如果您只有一个父级->一个子级关系,我将坚持使用
[参数]
EventCallBack
,这将使您的子组件更具可移植性和可重用性。但是,如果您需要一个值来传递多个级别的子组件,您可能有一个很好的理由来级联该值。您必须权衡每种方法的优缺点,但我鼓励您给出一些建议嗯