EditContext OnFieldChanged 报错返回类型

Posted

技术标签:

【中文标题】EditContext OnFieldChanged 报错返回类型【英文标题】:EditContext OnFieldChanged reporting wrong return type 【发布时间】:2021-10-30 10:31:02 【问题描述】:

我在 razor 文件中有以下 3 种方法

    protected override async Task OnInitializedAsync()
    
        EditContext = new EditContext(_projectModel);
        EditContext.OnFieldChanged += EditContext_OnFieldChanged;
    
    
    
    private async Task EditContext_OnFieldChanged(object sender, FieldChangedEventArgs e)
    
        await SetOkDisabledStatus();
    
    

这个方法是一个异步方法,我必须在任何地方等待它被调用

    private async Task SetOkDisabledStatus()
    
        if (EditContext.Validate())
        
            OkayDisabled = null;
            await JsRuntime.InvokeVoidAsync("Animate");
        
        else
        
            OkayDisabled = "disabled";
        
    
    
    

我在 Blazor 服务器应用程序中使用 EditContext 进行验证。

我在 OnInitializedAsync() 方法的下面这一行中收到错误消息,不知道如何继续。

    EditContext.OnFieldChanged += EditContext_OnFieldChanged;

错误信息:

任务 MyProject.EditContext_OnFieldChanged(object, FieldChangedEventArgs)' 返回类型错误。

期望一个带有 void EditContext_OnFieldChanged(object?, FieldChangedEventArgs e) 的方法

请注意,我正在使用 sonarqube 来检查我的所有代码。

【问题讨论】:

请按照以下代码建模您的代码 sn-p: protected override void OnInitialized() EditContext = new EditContext(Model); EditContext.OnFieldChanged += EditContext_OnFieldChanged; base.OnInitialized(); private void SetSaveDisabledStatus(FieldChangedEventArgs e) // 每次字段更改时,都会执行此代码。如果验证成功,EditContext.Validate() 返回 true;也就是说,两个字段都通过了验证,在这种情况下,我们将值 null 分配给属性 Disabled,从而启用 Save 按钮。 if (EditContext.Validate()) 禁用 = null; else 禁用 = "禁用"; 另外,我认为使用 JSInterop 不是一个好主意。我会使用 CSS 【参考方案1】:

您可以将异步 lambda 分配给事件处理程序,如下所示:

EditContext.OnFieldChanged += 
  async (sender,args) => await EditContext_OnFieldChanged(sender,args);

但是,您应该知道 EditContext/Form 不会await 您的任务。您在该异步任务中执行的任何操作都将与编辑上下文不同步。

您可能还应该在异步代码中包含取消标记,以便对字段的多次更改不会同时触发多个验证任务。

异步验证很难 - 确保测试所有可能的场景。

【讨论】:

值得一提的是,lambda 是一个async void,这不是那么容易看到的。你说得对,异步验证很难。 @HenkHolterman ??? 不错的评论 - 这不是我想到的,但有道理 - 你有任何参考吗? 不知道具体的引用,但编译器会推断void,而不是Task,返回类型,然后你应用async 修饰符。 OnFieldChanged 不能接受 Task 方法。【参考方案2】:

生成的 Blazor 事件处理程序(如 @onclick="...")在返回类型和参数方面是灵活的,但 EditContext.OnFieldChanged 不是,它具有固定的委托类型。

进行以下更改:

//private async Task EditContext_OnFieldChanged(object sender, FieldChangedEventArgs e)
  private async void EditContext_OnFieldChanged(object sender, FieldChangedEventArgs e)
  
     await SetOkDisabledStatus();
     StateHasChanged();  // make sure OkayDisabled takes effect
  
  

另一方面,您可以将 OkayDisabled 设为布尔值并在需要的地方使用 disabled="@OkayDisabled"。 当您使用 false 分配 disabled 属性时,Blazor 会使其消失。


替代方案:保持验证同步。正如@Mister Magoo 指出的那样,这可能会避免一些问题。然后只让动画异步运行。

private void EditContext_OnFieldChanged(object sender, FieldChangedEventArgs e)

   SetOkDisabledStatus();  


private void SetOkDisabledStatus()

    if (EditContext.Validate())
    
        OkayDisabled = null; 
        _ = JsRuntime.InvokeVoidAsync("Animate");  // no await, on purpose
    
    else
    
        OkayDisabled = "disabled";
    

在这种情况下不需要StateHasChanged()。

【讨论】:

这个答案不正确。不能使用 async void... 应该是:private void EditContext_OnFieldChanged(object sender, FieldChangedEventArgs e) 另外,不应使用 StateHasChanged 方法。 再说一次,为什么不呢?

以上是关于EditContext OnFieldChanged 报错返回类型的主要内容,如果未能解决你的问题,请参考以下文章

Blazor University (33)表单 —— EditContextFieldIdentifiers

qtableview 无法显示新插入的行

Core Data 持久化存储异步保存

Blazor University (35)表单 —— 编写自定义验证

请求适用于Postman,但不适用于axios.post