如何使组件 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);
}
几点:
- 我已将 Type 的显示移到
Select
之外。
- 每当使用
@ininput
更改值时,我都会触发 UI 更新。您不能使用 @onchange
,因为绑定进程使用该事件。
- 在现实生活中
model
也会移动到 Vehicle
服务,该服务将使用 CRUD 方法从相关数据存储中获取数据并将数据保存到相关数据存储中。
我试图在 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);
}
几点:
- 我已将 Type 的显示移到
Select
之外。 - 每当使用
@ininput
更改值时,我都会触发 UI 更新。您不能使用@onchange
,因为绑定进程使用该事件。 - 在现实生活中
model
也会移动到Vehicle
服务,该服务将使用 CRUD 方法从相关数据存储中获取数据并将数据保存到相关数据存储中。