子组件的Blazor onclick不会导致重新呈现

问题描述 投票:0回答:1

我有一个带有一个子组件的组件

<MyBtn Command="@ShowBusyCommand"></MyBtn>

@if(IsBusy)
{
<span>I'm busy</span>
}

@code{
 public bool IsBusy { get; set; }

 public ICommand ShowBusyCommand => RegisterCommand(() => ShowBusyCommand, CanExecute, ExecuteAsync);

 public async Task ExecuteAsync()
    {
        try
        {
            IsBusy = true;
            await Task.Delay(2000);
        }
        finally
        {
            IsBusy = false;
        }
    }
}

和MyBtn组件

<button @onclick="@Execute">Show busy</button>

@code {
    [Parameter]
    public ICommand Command { get; set; }

    public void Execute()
    {
        Command.Execute(null);
    }
}

当我单击按钮ExecuteAsync方法时,但视图未更改。我没有看到“我很忙”的文字。

我什至尝试在MyBtn中创建一个EventCallback

<button @onclick="@OnClickHandler">Show busy</button>

@code {
    [Parameter]
    public ICommand Command { get; set; }

    [Parameter] 
    public object Receiver { get; set; }

    public async Task OnClickHandler()
    {
        var onClick = EventCallback.Factory.Create(Receiver, () => Command.Execute(null));
        await onClick.InvokeAsync(null);
    }
}


  <MyBtn Command="@ShowBusyCommand" Receiver="this"></MyBtn>

但是那也没有帮助。

我不知道为什么在单击组件中的按钮时父状态不会改变,我该如何解决?除了在IsBusy属性更改时手动调用StateHasChanged。

如果我将参数从ICommand更改为MyBtn组件中的EventCallback,并传递ExecuteAsync方法,它将起作用。为什么?如何通过将ICommand作为参数传递并调用Execute方法来使其工作?

编辑:我只是想知道是否可以从EventCallback工厂中删除lambda,它可以工作,但我不知道为什么

var onClick = EventCallback.Factory.Create(Receiver, Command.Execute);
blazor blazor-server-side blazor-client-side
1个回答
1
投票

这是您的问题的有效代码...

Index.razor

@page "/"

<MyBtn Func="@ShowBusyAsync"></MyBtn>

@if(IsBusy)
{
<span>I'm busy</span>
}

@code{
 public bool IsBusy { get; set; }

 public async Task ShowBusyAsync(int delay)
    {
        try
        {
            IsBusy = true;
            await Task.Delay(delay);
        }
        finally
        {
            IsBusy = false;
        }
    }
}

MyBtn.razor

<h3>MyBtn</h3>

<button @onclick="@ExecuteAsync">Show busy</button>

@code {
    [Parameter]
    public EventCallback <int> Func { get; set; }

    public async void ExecuteAsync()
    {
        await Func.InvokeAsync(3000);
    }
    }

注意:如果您希望重新呈现父组件,则应使用EventCallback,因为EventCallback创建一个委托,该委托的Target属性设置为注册事件的对象,即父组件。如果您不希望父组件成为事件的目标,请改用Action或Func委托。

© www.soinside.com 2019 - 2024. All rights reserved.