Blazor按钮,使用父组件@onclick

时间:2020-06-18 11:07:36

标签: blazor

是否可以使用父组件方法@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'.

我确实想要一个子按钮组件,并且单击它(在父对象中呈现)时-我想在父组件中调用一个方法。

3 个答案:

答案 0 :(得分:3)

您不能以这种方式使用@onclick指令...该指令与Html元素一起使用,指示编译器为click事件创建事件处理程序,例如:

<button type="button" @onclick="ClickEventHandler">Click me</button>

@code{
   private void ClickEventHandler()
   {
      Cosole.WriteLine("Hello Blazor");
    }
}

但是,在绑定组件时,应该执行以下操作:

ChildComponent.razor

<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 ...

这是一个完整的工作代码段,展示了父组件与其子组件之间的双向数据绑定:

ParentComponent.razor

@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类型,有关更多信息,请参见文档。