【问题标题】:Execute async method on button click in blazor在 blazor 中单击按钮时执行异步方法
【发布时间】:2019-08-25 02:17:55
【问题描述】:

我创建了一个“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);
    }
}

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

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

提前致谢。

【问题讨论】:

    标签: c# razor blazor blazor-server-side razor-components


    【解决方案1】:

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

    <button onclick="@(async () => await Delete(person.Id))">❌</button>
    
    @functions {
    
        // ...
    
        async Task Delete(Guid personId)
        {
            await this.PersonRepository.Delete(personId);
        }
    }
    

    【讨论】:

    • 我想知道为什么每个人都创建不必要的异步状态机(在匿名方法上)。为什么不只是onclick="@(e =&gt; Delete(person.Id))"?顺便说一句:DeleteAsync 不会违反命名准则。
    • 唯一的问题是它不会异步调用该方法。长任务挂断主线程:(。
    【解决方案2】:

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

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

    【讨论】:

    • 谢谢,但该按钮位于 foreach(var person in perons) 循环内。您能否提供一些代码,您将如何实现这一点?感谢您对第二点的澄清。稍后我会试试看:)
    猜你喜欢
    • 2020-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多