![](/img/trans.png)
[英]Blazor binding is not working when calling a method from @ref component 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组件被实例化的组件。 请注意,您应该将父组件的上述属性设置为属性属性......您不能在组件实例化之外设置它们。 现在这是一个警告,但史蒂夫安德森已经很难过它很快就会成为编译器错误。 这是在父组件中实例化组件的方式:
<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 方法,你可以这样做:
<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.