如何使组件 class 的继承起作用?

How do I make inheritance work from component class?

我试图在 If 语句中从组件 class 访问 ID,但收到错误消息,指出它在当前上下文 (CS0103) 中不存在。

这是我的代码:

    @inherits MainViewModel

<button>Delete</button>
<button>Add</button>
<br />
<label>Vehicles</label>

<EditForm Model="@VehicleFuel">
    <InputSelect Id="VehicleList" class="form-group" @bind-Value="@Id">
        <option value="0">Select a vehicle</option>
        @foreach (var item in VehicleFuel)
        {
            <option value="@item.VehicleId">@item.VehicleFuel</option>
        }

        @if (@VehicleId = 1)
        {
        <div>
            <p>Manufacturer</p>
            <input placeholder="Tesla" />
        </div>

        <div>
            <p>Model</p>
            <input placeholder="Model 3" />
        </div>
        } 
    </InputSelect>
</EditForm>

这是我的组件 class:

using Microsoft.AspNetCore.Components;
using System.Collections.Generic;
using System.Threading.Tasks;
using VehicleSale.Models;

namespace VehicleSale.Components;

    public class MainViewModel : ComponentBase
    {
        public List<VehicleTypes> VehicleFuel  { get; set; }
        public string Id {get; set; } = "0";

        protected override Task OnInitializedAsync()
        {
            VehicleFuel = new List<VehicleTypes>()
            {
                new VehicleTypes{VehicleId=1, VehicleFuel="Electric"},
                new VehicleTypes{VehicleId=2, VehicleFuel="Gas"},
                new VehicleTypes{VehicleId=3, VehicleFuel="Diesel"}
            };
            return base.OnInitializedAsync();
        }

我很困惑我需要在哪里再次添加组件 class 以便我可以在我的 if 语句中使用它。 My end goal is that when either the VehicleID or VehicleFuel is selected, the following input box appear which would be the Manufacturer and Model.我试过写@VehicleFuel,但我得到了同样的错误。

您应该使用相同类型的 int 绑定到 int。您的绑定语法也是错误的。您的 if 语句是一个赋值使用 ==is.

@inherits MainViewModel

<button>Delete</button>
<button>Add</button>
<br />
<label>Vehicles</label>

<EditForm Model=@this.someModel>
    <InputSelect Id="VehicleList" class="form-group" @bind-Value="@someModel.VehicleId">
        <option value=0>Select a vehicle</option>
        @foreach (var item in VehicleFuel)
        {
            <option value="@item.VehicleId">@item.VehicleFuel</option>
        }
    </InputSelect>
</EditForm>
@if (this.someModel.VehicleId is 1)
{
    <div>
        <p>Manufacturer</p>
        <input placeholder="Tesla" />
    </div>

    <div>
        <p>Model</p>
        <input placeholder="Model 3" />
    </div>
}
public class MainViewModel : ComponentBase
{
    protected SomeModel someModel  = new();
    protected List<VehicleTypes> VehicleFuel { get; set; }

    protected override Task OnInitializedAsync()
    {
        VehicleFuel = new List<VehicleTypes>()
        {
            new VehicleTypes{VehicleId=1, VehicleFuel="Electric"},
            new VehicleTypes{VehicleId=2, VehicleFuel="Gas"},
            new VehicleTypes{VehicleId=3, VehicleFuel="Diesel"}
        };    
    }
}

public class SomeModel
{
    public int VehicleId { get; set; } = 0;
}

public class VehicleTypes
{
    public int VehicleId { get; set; }
    public string VehicleFuel { get; set; }
}

我假设您实现了继承,因此您可以在多个 children.

中使用 VehicleFuel

通过将数据与 UI.

分开,您可以采用不同的“简洁设计”方法来解决此问题

定义一个包含您的车辆燃料数据的 DI 服务。它可以像在内部创建列表一样简单,也可以从数据库或 API 服务等数据存储中获取列表。

首先是一些数据类。

public record VehicleType
{
    public int VehicleId { get; init; }
    public string VehicleFuel { get; init; } = "Diesel";
}

public class Vehicle
{
    public int VehicleTypeId { get; set; }
}

燃料服务:

public class FuelService
{
    public List<VehicleType> VehicleFuel { get; private set }

    public FuelService()
    {
        // define it in code but could get it from a DB
        VehicleFuel =new List<VehicleType>()
        {
                new VehicleType{VehicleId=1, VehicleFuel="Electric"},
                new VehicleType{VehicleId=2, VehicleFuel="Gas"},
                new VehicleType{ VehicleId = 3, VehicleFuel = "Diesel" }
        };
    }
}

Program.cs中注册。我正在使用单例,因为它是所有用户的相同数据集。

builder.Services.AddSingleton<FuelService>();

我们现在可以 Inject 服务到任何需要使用它的组件中。

@page "/"
@inject FuelService FuelService

<EditForm Model="@model">
    <InputSelect Id="VehicleList" class="form-group" @bind-Value="@model.VehicleTypeId" @oninput=UpdateUI>
        <option value="0">Select a vehicle</option>
        @foreach (var item in this.FuelService.VehicleFuel)
        {
            <option value="@item.VehicleId">@item.VehicleFuel</option>
        }

    </InputSelect>
</EditForm>
<div class="p-2">
@if (@model?.VehicleTypeId == 1)
{
    <div>
        <span style="display:block;">Manufacturer</span>
        <input placeholder="Tesla" />
    </div>

    <div>
        <span style="display:block;">Model</span>
        <input placeholder="Model 3" />
    </div>
}
</div>
@code {

    private Vehicle model = new Vehicle();

    private void UpdateUI()
    =>  this.InvokeAsync(StateHasChanged);
}

几点:

  1. 我已将 Type 的显示移到 Select 之外。
  2. 每当使用 @ininput 更改值时,我都会触发 UI 更新。您不能使用 @onchange,因为绑定进程使用该事件。
  3. 在现实生活中 model 也会移动到 Vehicle 服务,该服务将使用 CRUD 方法从相关数据存储中获取数据并将数据保存到相关数据存储中。