在 Blazor 的父组件中获取子组件绑定值

smj*_*smj 9 c# blazor

假设名为 cinput.cshtml 的子组件是

<input type="text" bind="@username">

@functions{
string username;
}
Run Code Online (Sandbox Code Playgroud)

和名为 pform.cshtml 的父组件

<cinput></cinput>
<input type="text" bind="@email">
<input type="button" onclick="@onsubmit">

@functions{

string email;

public void onsubmit(){
   //Call api
}
}
Run Code Online (Sandbox Code Playgroud)

所以问题是如何在父组件中获取用户名值?

Isa*_*aac 13

您应该执行以下操作:

  1. 在子组件中定义一个 EventCallback 委托属性:
[Parameter] protected  EventCallback<string>  OnUserNameChanged { get; set; }
Run Code Online (Sandbox Code Playgroud)

此属性将包含对父组件上定义的方法的委托。

  1. 在子组件中定义一个属性和一个支持变量:
    private string username;
    public string UserName
    {
        get => username;
        set
        {
            username = value;
            // Invoke the delegate passing it the changed value
            OnUserNameChanged?.Invoke(value);
        }
    } 
Run Code Online (Sandbox Code Playgroud)
  1. 在您的父组件中定义一个方法,当用户名更改时从子组件调用该方法:
    public async void UserNameChanged(string username)
       {
          // Gets and consume the user name
       }
Run Code Online (Sandbox Code Playgroud)
  1. 这就是子组件在父组件中的使用方式:请注意,我们将方法名称分配给属性 OnUserNameChanged,这是子组件中的委托属性
     <cinput OnUserNameChanged="UserNameChanged" ></cinput>
        <input type="text" bind="@email">
        <input type="button" onclick="@onsubmit">
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助...

这就是史蒂夫·安德森 (Steve Anderson) 对 ref 的看法:

用例

预期用例是允许父组件向子组件发出命令,例如“show”或“reset”。

即便如此,在架构上它也是一种妥协,因为如果你的子组件是无状态的(也就是说,不作用于它们的参数以外的任何状态),它会更干净,在这种情况下,理论上它甚至不可能发出除了更改孩子的参数之外的“操作”,在这种情况下,您根本不需要 ref 。

这是强烈不推荐您使用REF为突变子组件的状态的一种方式。相反,始终使用普通的声明性参数将数据传递给子组件。这将导致子组件在正确的时间自动重新渲染。我们正在努力改变组件上参数的表示方式,以便默认情况下它们被封装并且无法从外部读取/写入。

  • 如果我想以同一形式使用子对象的多个实例,此解决方案是否有效 (3认同)

smj*_*smj 0

所以我做了这样的事情

cinput.cshtml

<input type="text" bind="@username">

@functions{
string username;

string getUsername(){
 return username;
}

}
Run Code Online (Sandbox Code Playgroud)

在 pform.cshtml 中

<cinput ref="_cinput"></cinput>
<input type="text" bind="@email">
<input type="button" onclick="@onsubmit">

@functions{

string email;
Cinput _cinput

public void onsubmit(){
   //get username
   string uname = _cinput.getUsername();
   //Call api

}
}
Run Code Online (Sandbox Code Playgroud)

https://learn.microsoft.com/en-us/aspnet/core/razor-components/components?view=aspnetcore-3.0#capture-references-to-components