34

我创建了一个“Razor Components”项目。我试图在按下按钮时执行异步方法,但还无法弄清楚语法。

这是我的Index.razor

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

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

@functions 
{
    async void Delete(Guid personId)
    {
        await this.PersonRepository.Delete(personId);
    }
}

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

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

提前致谢。

4

2 回答 2

46

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

<button onclick="@(async () => await Delete(person.Id))">❌&lt;/button>

@functions {

    // ...

    async Task Delete(Guid personId)
    {
        await this.PersonRepository.Delete(personId);
    }
}
于 2019-04-03T14:13:58.123 回答
17

@WoIIe,1. 使用 lambda 表达式作为 onclick 属性的值的目的是,您可以将值传递给 Delete 方法。如果您已经在代码中定义了 person 对象,则不必使用 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);
    }
}

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

 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);
}
}

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

于 2019-04-03T17:36:07.777 回答