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