是否可以使用父组件方法@onclick,还是需要从子对象中调用它?
假设我要调用父方法Foo()。
父母
@page "/"
// Custom component button
<Button Text="Some text" @onclick="Foo" Apperance="@Style.secondary" />
@code {
async Task Foo()
{
// ...
}
}
孩子
<button class="btn @_cssClass"><span>@Text</span></button>
@code {
public enum Style
{
primary,
secondary,
tertiary,
danger
}
[Parameter]
public string Text { get; set; }
[Parameter]
public Style Apperance { get; set; }
private string _cssClass { get; set; }
protected override void OnInitialized()
{
_cssClass = Apperance switch
{
Style.secondary => "btn--secondary",
Style.tertiary => "btn--tertiary",
Style.danger => "btn--danger",
_ => "btn--primary"
};
}
}
我收到此错误:
Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] Unhandled exception rendering component: Object of type 'Tidrapport.Client.Components.Button' does not have a property matching the name 'onclick'. System.InvalidOperationException: Object of type 'Tidrapport.Client.Components.Button' does not have a property matching the name 'onclick'.
我确实想要一个子按钮组件,并且单击它(在父对象中呈现)时-我想在父组件中调用一个方法。
答案 0 :(得分:3)
您不能以这种方式使用@onclick指令...该指令与Html元素一起使用,指示编译器为click事件创建事件处理程序,例如:
<button type="button" @onclick="ClickEventHandler">Click me</button>
@code{
private void ClickEventHandler()
{
Cosole.WriteLine("Hello Blazor");
}
}
但是,在绑定组件时,应该执行以下操作:
<input type="text" @bind="Text" @bind:event="oninput" />
@code {
private string text { get; set; }
[Parameter]
public string Text
{
get { return text; }
set
{
if (text != value) {
text = value;
if (TextChanged.HasDelegate)
{
TextChanged.InvokeAsync(value);
}
}
}
}
[Parameter]
public EventCallback<string> TextChanged { get; set; }
}
如您所见,我已经定义了一个名为Text的参数Property ...为了创建双向数据绑定,还应该定义一个EventCallback'delegate',其作用是更新父对象中的绑定对象零件。因此,您将在父组件中编写代码:
<ChildComponent @bind-Text="Text" />
请注意,EventCallback委托的名称由Text单词和Changed单词组成。
@ bind-Text指令将子组件中定义的Text属性绑定到父组件中定义的Text属性(请参见下面的代码)。
因此,规则为@bind-
加上子组件中属性的名称,例如Value
转到@bind-Value
,其值应为属性的名称,例如MyValue
,因此:@bind-Value="MyValue"
但是,在子组件中,您应该定义一个名为Value的参数属性和一个名为EventCallback
...的ValueChanged
...
这是一个完整的工作代码段,展示了父组件与其子组件之间的双向数据绑定:
@page "/ParentComponent"
<h1>Parent Component</h1>
<input type="text" @bind="Text" @bind:event="oninput" />
<p></p>
<ChildComponent @bind-Text="Text" />
@code {
[Parameter]
public string Text { get; set; } = "Hello Blazor";
}
希望这行得通...
答案 1 :(得分:1)
因此,我确实需要一个子按钮组件,并且单击它时-我想在父组件中调用一个方法。
您的ChildComponent应该看起来像这样:
<button type="button" @onclick="CallMethodParent">Call a method on parent component</button>
@code {
[Parameter]
public EventCallback<string> ParentMethod { get; set; }
private async Task CallMethodParent()
{
if(ParentMethod.HasDelegate)
{
await ParentMethod.InvokeAsync("A message from child component...");
}
}
}
<p>@message</p>
<ChildComponent ParentMethod="ParentMethod"/>
@code{
private string message;
private void ParentMethod(string message)
{
this.message = message;
}
}
注意:要从中获得的主要好处是,您应该在子组件中定义一个参数EventCallback属性,该属性存储在父组件中定义的方法。
希望这对您有帮助...
答案 2 :(得分:0)
因此,我已经找到了问题的答案,您设计了在docs中找到的EventCallback
。
对我来说,看起来像这样。
父母
@page "/"
// Custom component button
<Button Text="Some text" OnClickCallback="@Foo" Apperance="@Style.secondary" />
@code {
async Task Foo()
{
// ...
}
}
孩子
<button class="btn @_cssClass" @onclick="OnClickCallback"><span>@Text</span></button>
@code {
public enum Style
{
primary,
secondary,
tertiary,
danger
}
[Parameter]
public string Text { get; set; }
[Parameter]
public Style Apperance { get; set; }
private string _cssClass { get; set; }
[Parameter]
public EventCallback OnClickCallback { get; set; } // this is where to you pass the parent function to be executed as a callback
protected override void OnInitialized()
{
_cssClass = Apperance switch
{
Style.secondary => "btn--secondary",
Style.tertiary => "btn--tertiary",
Style.danger => "btn--danger",
_ => ""
};
}
}
因此onclick事件绑定到您在子组件中设计的事件处理程序。如果要使用参数,可以为T
类型,有关更多信息,请参见文档。