<EditForm> 里面的 Blazor <InputSelect>?

Blazor <InputSelect> inside <EditForm>?

我什么都试过了,在谷歌上搜索了很多,仍然无法正常工作。我正在尝试使用 <EditForm><InputSelect> 来更新现有对象(在我的例子中是 video)。

  1. 我想要 InputSelect@bind-Value="video.DisplayId"。那么第一个 selected 选项将是;要么 1. if video.DisplayId is null,然后显示 "None"。 2. if video.DisplayId is not null, 显示对象名称(video.Display.Name).

  2. 然后将 displays 的整个列表加载到带有 foreach 的选项中,除了当前 selected.

  3. If video.DisplayId is not null 然后在末尾添加一个选项 "None".

加载 Blazor 页面时,所有值看起来都很好,当我 select 即从 video.Display.Name"None" 并点击保存时,它起作用了。

但是当我从 "None" 转到 display.Name 时,它说对象引用未设置为对象的实例(请参阅下面我的代码,其中有说明)。

我的代码:

<InputSelect class="form-select" @bind-Value="video.DisplayId">
    @if (video.DisplayId is null)
    {
        <option selected value="">None</option>
    }
    else 
    {
        // Object reference not set to an instance of an object ....
        <option selected value="@video.DisplayId">@video.Display.Name</option>
    }
    @foreach (Display display in displays.Where(display => display.Id != video.DisplayId))
    {
        <option value="@display.Id">@display.Name</option>
    }
    @if (video.DisplayId is not null)
    {
        <option value="">None</option>
    }
</InputSelect>

我认为这与 Blazor 以及它在我 select 之后呈现页面的方式有关,但我该如何解决这个问题?

@page "/"

<EditForm Model=@video>
    <InputSelect @bind-Value=@video.DisplayId>
        @if (video.DisplayId is null)
        {
            <option value="">none</option>
        }
        else
        {
            <option value=@selectedDisplay?.Id>@selectedDisplay?.Name</option>
        }
        @foreach (var display in unSelectedDisplays)
        {
            <option value=@display.Id>@display.Name</option>
        }
        @if (video.DisplayId is not null)
        {
            <option value="">none</option>
        }
    </InputSelect>
</EditForm>

@code {
    private Video video = new Video();
    private IEnumerable<Display> displays = Enumerable.Empty<Display>();

    private IEnumerable<Display> unSelectedDisplays => 
        displays.Where(display => display.Id != video.DisplayId);

    Display? selectedDisplay => video.DisplayId.HasValue ?
                            displays.First(d => d.Id == this.video.DisplayId) :
                            default(Display);

    protected override void OnInitialized()
    {
        displays = Enumerable.Range(0, 10)
            .Select(i => new Display { Id = i, Name = $"Name{i}" });
    }

    public class Display
    {
        public int Id { get; set; }

        public string? Name { get; set; }
    }

    public class Video
    {
        public int? DisplayId { get; set; }
    }
}

又过了几个小时,我明白了。我需要将代码重写为以下内容:

<InputSelect class="form-select" @bind-Value="video.DisplayId">
    @if (video.DisplayId is null)
    {
        <option selected value="">None</option>
    }
    @foreach (Display display in displays)
    {
        <option value="@display.Id">@display.Name (ID: @display.Id)</option>
    }
    @if (video.DisplayId is not null)
    {
        <option value="">None</option>
    }
</InputSelect>

按下保存后,它会调用我的方法,在我的方法中它正在更改数据库中的数据,然后我不得不再次从数据库中获取列表。