繁体   English   中英

如何在 Blazor 中通过 @Ref 获得的 Reference 设置组件属性

[英]How in Blazor Set component properties through a Reference that obtained by @Ref

我有一个组件,我在页面变量中设置了它的引用:

<BlazorWebFormsComponents.Button OnClick="@((args) => btnForms_Clicked(formsButton, args))" @ref="formsButton" Text="Forms Button" CssClass="btn btn-primary">
    
</BlazorWebFormsComponents.Button>

在事件处理程序中,我设置了一个按钮属性(文本):

Button formsButton;

public void btnForms_Clicked(object sender, MouseEventArgs e)
{                        
    if (sender is Button)
        (sender as Button).Text = "Good Bye";
}

对于大多数 Button 属性,此代码不起作用,对于 BackColor 有效,但对于 Text 无效。 blazor 也做了分配线,绿色下划线并说“组件参数“zzz”不应该设置在其组件之外”,那么为什么 Blazor 提供了一个 @Ref 而大多数引用的属性都无法设置? 还是有办法使这项工作?

我不是 Blazor 的出口,但也遇到了这个问题。 您可以通过绑定到页面上的属性来做到这一点。

<BlazorWebFormsComponents.Button OnClick="@((args) => btnForms_Clicked(formsButton, args))" @ref="formsButton" Text="@ButtonText" CssClass="btn btn-primary">

</BlazorWebFormsComponents.Button>

@code{
    private string ButtonText { get; set; } = "Forms button";

    public void btnForms_Clicked(object sender, MouseEventArgs e)
    {
        ButtonText = "Good bye";
    }
}

我从未使用过@Ref,也不知道如何或何时使用它。

出现警告是因为从代码中设置[Parameter]属性会导致渲染树不同步,并导致组件的双重渲染。

如果您需要从代码中设置某些内容,您可以在组件 class 上公开一个公共方法,例如SetText ,它会为您执行此操作。

在内部,组件[Parameter]应该引用一个局部变量。

string _text;
[Parameter] 
public string Text { get => _text; set => SetText(value);}
public void SetText(string value)
{
  _text = value;
}

我不是在推广这种方法,我更喜欢在@Pidon 的回答中使用这种方法。 此外,您可以考虑 - 也许您有太多参数,应该考虑使用 Options 参数来合并

<Button OnClick="@((args) => btnForms_Clicked(formsButton, args))" @ref="formsButton" Text="Forms Button" CssClass="btn btn-primary">

您的 Button 组件应定义如下:

@code
{
    [Parameter]
    public EventCallback<MouseEventArgs> OnClick {get; set;} 
    [Parameter]
    public string Text {get; set;} 

}

上面的代码定义了两个应该从 Parent 组件分配的参数属性。 父组件是Button组件被实例化的组件。 请注意,您应该将父组件的上述属性设置为属性属性......您不能在组件实例化之外设置它们。 现在这是一个警告,但史蒂夫安德森已经很难过它很快就会成为编译器错误。 这是在父组件中实例化组件的方式:

父.razor

<Button OnClick="@((args) => btnForms_Clicked(args))" @ref="formsButton" 
      Text="_text" CssClass="btn btn-primary">
    
</Button>

@code
{
private Button formsButton;

// Define a local variable wich is bound to the Text parameter
private string _text = "Click me now...";

public void btnForms_Clicked( MouseEventArgs e)
{                        
    _text = "You're a good clicker.";
}
}

注意:当您点击 Button 组件时,应在 Button 组件中引发单击事件,并且按钮组件应将此事件传播到父组件; 也就是在父组件上执行 btnForms_Clicked 方法,你可以这样做:

按钮.razor

<div @onclick="InvokeOnClick">@Text</div>

@code
    {
        [Parameter]
        public EventCallback<MouseEventArgs> OnClick {get; set;} 
        [Parameter]
        public string Text {get; set;} 

        private async Task InvokeOnClick ()
        {
             await OnClick.InvokeAsync(); 
        }
    
    } 

请注意,为了演示如何在 Button 组件中引发事件并将其传播到父组件,我使用的是 div 元素,但您可以使用按钮元素等。

@onclick是一个编译器指令,指示创建一个 EventCallback 'delegate',其值为事件处理程序InvokeOnClick 现在,每当您单击 div 元素时,都会引发click事件,并调用事件处理程序InvokeOnClick ...从该事件中我们执行 EventCallback 'delegate' OnClick 换句话说,我们调用父组件中定义的 btnForms_Clicked 方法。

那么@ref指令有什么用呢? 您可以使用@ref 指令来获取对包含要从其父组件调用的方法的组件的引用:假设您定义了一个用作对话框小部件的子组件,并且该组件定义了一个Show方法,当被调用,显示对话框小部件。 这很好且合法,但切勿尝试在组件实例化之外更改或设置参数属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM