在blazor中单击按钮时执行异步方法

WoI*_*IIe 4 c# razor blazor blazor-server-side razor-components

我创建了一个“剃刀组件”项目。我正在尝试在按下按钮时执行异步方法,但仍无法弄清楚语法。

这是我的Index.razor

@page "/"
@inject GenericRepository<Person> PersonRepository 

// ...

@foreach (var person in persons)
{
    <button onclick="@(() => Delete(person.Id))">?</button>
}

@functions {

    // ...

    async void Delete(Guid personId)
    {
        await this.PersonRepository.Delete(personId);
    }
}
Run Code Online (Sandbox Code Playgroud)

当我单击按钮时,什么也没有发生。我尝试了各种返回类型(例如Task)和东西,但无法弄清楚如何使其工作。如果需要提供更多信息,请告诉我。

每个文档/教程仅在按钮单击时仅适用于非异步void调用。

提前致谢。

Dav*_*idG 39

您需要Delete正确调用该方法并使其返回Task而不是void

<button onclick="@(async () => await Delete(person.Id))">?</button>

@functions {

    // ...

    async Task Delete(Guid personId)
    {
        await this.PersonRepository.Delete(personId);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我想知道为什么每个人都创建不必要的异步状态机(在匿名方法上)。为什么不只是`onclick="@(e =&gt; Delete(person.Id))"`?顺便说一句:`DeleteAsync` 不会违反命名准则。 (8认同)
  • 唯一的问题是它不会异步调用该方法。长任务会挂起主线程:(。 (3认同)
  • 您介意在这篇文章中添加一些有关[异步调用的新建议](/sf/answers/4234180051/)的信息吗?我一直把这篇文章作为第一个搜索结果,却总是忘记还有更好的方法。 (2认同)

Isa*_*aac 7

@WoIIe,1.使用lambda表达式作为onclick属性的值的目的是使您可以将值传递给Delete方法。如果您已经在代码中定义了人员对象,则不必使用lambda表达式。只需执行以下操作:onclick = "@Delete",然后从Delete方法访问person.Id。

  1. 您是否第二次单击该按钮?我相信这段代码:await this.PersonRepository.Delete(personId);确实执行了,但是您在GUI上没有看到任何响应,因为不建议使用void,这要求您调用StateHasChanged();。手动重新渲染。请注意,当方法“结束”时,StateHasChanged()已被自动调用一次,但是由于返回的是void而不是Task,因此应再次调用StateHasChanged()来查看更改。但是不要这样做。请参阅DavidG的答案,如何正确编码。

这也是您可以编码的方式:

<button onclick="@Delete">Delete Me</button>

@functions {

    Person person = new Person();
    //....
    async Task Delete()
    {
        await this.PersonRepository.Delete(person.Id);
    }
}
Run Code Online (Sandbox Code Playgroud)

根据要求提供更多代码...

 foreach(var person in people)
    {
        <button onclick="@(async () => await Delete(person.Id))">Delete</button>
    }

@functions {
  // Get a list of People.
  List<Person> People ;

protected override async Task OnParametersSetAsync()
{
    People = await this.PersonRepository.getAll();
}

async Task Delete(Guid personId)
{
     await this.PersonRepository.Delete(personId);
}
}
Run Code Online (Sandbox Code Playgroud)

注意:如果您仍未解决问题,请显示所有代码