在 Blazor 中异步设置 EditContext

Set EditContext asynchronously in Blazor

我有一个页面,它在 OnParametersSet 中加载了一个模型。该模型可以在表单中进行编辑。当我通过 Model="ViewModel.Something" 直接向 EditForm 提供模型时,这非常有效。但是我无法使用 EditContext 使其工作,因为 EditContext 想要在 OnParametersSet 中初始化。

Unhandled exception rendering component: EditForm requires either a Model parameter, or an EditContext parameter, please provide one of these.
System.InvalidOperationException: EditForm requires either a Model parameter, or an EditContext parameter, please provide one of these.
   at Microsoft.AspNetCore.Components.Forms.EditForm.OnParametersSet()
   at Microsoft.AspNetCore.Components.ComponentBase.CallOnParametersSetAsync()
   at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()

代码:

@inject SomeViewModel ViewModel

@if(ViewModel.Something != null)
{
    <EditForm EditContext="editContext" OnValidSubmit="@Submit">
        // ...
    </EditForm>
}

@code
{
    [Parameter] public string? SomethingId { get; set; } = String.Empty;

    private EditContext editContext { get; set; } = default!;

    protected override void OnInitialized()
    {
        base.OnInitialized();

        ViewModel.PropertyChanged += (o, e) => StateHasChanged();

        ViewModel.LoadSomething.Subscribe(_ => editContext = new(ViewModel!.Something));
    }

    protected override void OnParametersSet()
    {
        base.OnParametersSet();

        if(!string.IsNullOrEmpty(SomethingId))
        {
            ViewModel.Query = new LoadSomethingQuery(SomethingId);
        }
    }

    //...
}

我想使用 EditContext 的 IsModified 属性。因此我需要使用 EditContext 而不是模型。但是如果EditContext是在页面初始化之后才初始化的,就不行了。知道如何解决这个问题吗?

  • 一个选项是检查 editContext 是否存在空值:

    @if(editContext != null)
    {
        <EditForm EditContext="editContext" OnValidSubmit="@Submit">
            // ...
        </EditForm>
    }
    
  • 另一个选项 - 在 ctor 或 OnInitialized 中创建 EditContext,并在 OnParametesSet 中用新实例替换它:

    protected override void OnInitialized()
    {
        base.OnInitialized();
        editContext = new EditContext(...);
        ...
    }
    
    protected override void OnParametersSet()
    {
        base.OnParametersSet();
    
        if(!string.IsNullOrEmpty(SomethingId))
        {
            ViewModel.Query = new LoadSomethingQuery(SomethingId);
            ...
            editContext = new EditContext(...);
        }
    }