C# 父组件如何订阅子组件的SpeedChanged事件?

C# 父组件如何订阅子组件的SpeedChanged事件?,c#,asp.net-core,blazor,C#,Asp.net Core,Blazor,我有一个子组件,名为Earth,如下所示 <h3>Earth's speed is @Speed unit.</h3> @code { [Parameter] public double Speed { get; set; } [Parameter] public EventCallback<double> SpeedChanged { get; set; } } @page "/God" <Earth @bin

我有一个子组件,名为
Earth
,如下所示

<h3>Earth's speed is @Speed unit.</h3>

@code {
    [Parameter] public double Speed { get; set; }
    [Parameter] public EventCallback<double> SpeedChanged { get; set; }
}
@page "/God"

<Earth @bind-Speed="speed" SpeedChanged="Job" />

<button @onclick="@(()=>speed=0)">Stop Spinning!</button>

@code {
    private double speed = 100.0;
    private void Job(double s)
    {
        Console.WriteLine($"Earth's speed: {s}");
    }
}
在这里,我试图通过订阅
Earth
组件的
SpeedChanged

<Earth @bind-Speed="speed" SpeedChanged="Job" />
相当于

<Earth @bind-Speed="speed" @bind-Speed:event="SpeedChanged" />
<Earth @bind-Speed="speed" @bind-Speed:event="SpeedChanged" />

当您实现组件数据绑定时,您应该定义两个参数属性,就像您实际做的那样:

[Parameter] public double Speed { get; set; }
[Parameter] public EventCallback<double> SpeedChanged { get; set; }
[参数]公共双速{get;set;}
[参数]公共事件回调速度更改{get;set;}
要将此子组件绑定到父组件的属性,请执行以下操作:

<Earth @bind-Speed="speed"/>

这将在父组件和子组件之间创建双向数据绑定

注意:您没有为SpeedChanged属性提供值。这是隐含的,这就是为什么当您尝试这样做时会出现错误,因为编译器将自己执行此操作。编译器插入从子级绑定到父级的代码

从微软的文档中,我明白了这一点

<Earth @bind-Speed="speed" />
<Earth @bind-Speed="speed" />

相当于

<Earth @bind-Speed="speed" @bind-Speed:event="SpeedChanged" />
<Earth @bind-Speed="speed" @bind-Speed:event="SpeedChanged" />

那是真的,但你在做别的事。。。正如我所说,编译器将添加SpeedChanged…现在,如果您尝试手动添加它,就好像您使用它两次…不允许

在输入元素和属性之间创建双向数据绑定时,如下所示:

<input type="text" @bind="MyProperty"/>

编译器在幕后创建绑定,就像您编写的:

<input type="text" value="MyProperty" @onchange="@((args)=>MyProperty=args.Value.ToString())"/>


现在,如果您编写了类似于
的代码,编译器将开始尖叫onchange已经被使用了。代码也会发生同样的情况。

当您实现组件数据绑定时,您应该定义两个参数属性,就像您实际做的那样:

[Parameter] public double Speed { get; set; }
[Parameter] public EventCallback<double> SpeedChanged { get; set; }
[参数]公共双速{get;set;}
[参数]公共事件回调速度更改{get;set;}
要将此子组件绑定到父组件的属性,请执行以下操作:

<Earth @bind-Speed="speed"/>

这将在父组件和子组件之间创建双向数据绑定

注意:您没有为SpeedChanged属性提供值。这是隐含的,这就是为什么当您尝试这样做时会出现错误,因为编译器将自己执行此操作。编译器插入从子级绑定到父级的代码

从微软的文档中,我明白了这一点

<Earth @bind-Speed="speed" />
<Earth @bind-Speed="speed" />

相当于

<Earth @bind-Speed="speed" @bind-Speed:event="SpeedChanged" />
<Earth @bind-Speed="speed" @bind-Speed:event="SpeedChanged" />

那是真的,但你在做别的事。。。正如我所说,编译器将添加SpeedChanged…现在,如果您尝试手动添加它,就好像您使用它两次…不允许

在输入元素和属性之间创建双向数据绑定时,如下所示:

<input type="text" @bind="MyProperty"/>

编译器在幕后创建绑定,就像您编写的:

<input type="text" value="MyProperty" @onchange="@((args)=>MyProperty=args.Value.ToString())"/>


现在,如果您编写了类似于
的代码,编译器将开始尖叫onchange已经被使用了。代码也会发生同样的情况。

这是因为
@bind Speed
会自动查找并连接
SpeedChanged
。如果要手动执行此操作,请尝试此
这是因为
@bind Speed
会自动查找并连接
SpeedChanged
。如果要手动执行此操作,请尝试此
,它是正确的。因此,
public EventCallback SpeedChanged{get;set;}
应设置为
private
,以便“客户端”无法访问它。这是一个设计问题,你知道吗?我们以前必须将属性定义为private,但当前Blazor设计要求您将属性定义为public…这是一个很好的信息。非常感谢。这是真的。因此,
public EventCallback SpeedChanged{get;set;}
应设置为
private
,以便“客户端”无法访问它。这是一个设计问题,你知道吗?我们以前必须将属性定义为private,但当前Blazor设计要求您将属性定义为public…这是一个很好的信息。非常感谢。