如何在 blazor 中使用 Titem 制作具有多项选择和通用性的 table?
how to make a table with multiple selection and generic, using Titem in blazor?
我想制作一个 table component
,使用可重复使用的多选 Titem,我设法进行了多选,但无法制作 component reusable
,有什么建议吗?
我有一个可重复使用的 table,它是我通过查看来自 Microsoft https://docs.microsoft.com/en-us/aspnet/core/blazor/components/templated-components?view=aspnetcore-5.0 的直接示例制作的
这是我的代码:
@page "/multiple"
<div class="table-responsive">
<table class="table table-sm table-bordered table-hover">
<thead class="thead-dark">
<tr>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
@if (valueList != null)
{
int count = valueList.Count;
for (var i = 0; i < count; i++)
{
int current = i; // don't use loop variable in binding
var values = valueList[current];
<tr class="@values.Class" @onclick="((e) => SelectItems(current, true))">
<td>@values.Name</td>
<td>@values.Age</td>
</tr>
}
}
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<button type="button" class="btn btn-sm btn-info" @onclick="showSelected">Click</button>
<hr />
@if (events != null)
{
<ul>
@foreach (var evt in events)
{
<li>@evt</li>
}
</ul>
}
@code
{
//Declare various lists and classes.
private List<Value> valueList;
private List<string> events = new List<string>();
class Value
{
public string Name { get; set; }
public string Age { get; set; }
public string Class { get; set; }
}
//OnInitialized function to instantiated the valueList.
protected override void OnInitialized()
{
valueList = new List<Value>();
valueList.Add(new Value()
{
Name = "James",
Age = "38"
});
valueList.Add(new Value()
{
Name = "John",
Age = "32"
});
}
//Function to set selected class on tr. Can multi-select or single via Toggle bool.
void SelectItems(int index, bool toggle)
{
var item = valueList[index];
//If toggle then allow multiple to be selected. If class already selected then clear.
if (toggle)
{
if (item.Class == "selected")
{
item.Class = "";
}
else
{
item.Class = "selected";
}
}
else
{
foreach (var value in valueList)
{
value.Class = "";
}
// set the value
item.Class = "selected";
}
}
//Function to show the selected items.
void showSelected()
{
events.Clear();
foreach (var value in valueList)
{
if (value.Class.Contains("selected"))
{
events.Add($"'{value.Name}' selected. With value: '{value.Age}'");
};
}
}
}
这个table已经是一个可重复使用的组件了,我怎样才能让它成为多选table:
<table class="@TableClass">
<thead class="@TheadClass">
<tr>
@Cabecera
</tr>
</thead>
<tbody>
@foreach (var item in ItemList)
{
<tr>@Filas(item)</tr>
}
</tbody>
<tfoot>
<tr>
@Pie
</tr>
</tfoot>
</table>
@code{
[Parameter] public string ClassTable { get; set; }
[Parameter] public string ClassThead { get; set; }
[Parameter] public RenderFragment Cabecera { get; set; }
[Parameter] public RenderFragment Pie { get; set; }
[Parameter] public RenderFragment<TItem> Filas { get; set; }
[Parameter] public IEnumerable<TItem> Items { get; set; }
IEnumerable<TItem> ItemList { get; set; }
protected override async Task OnInitializedAsync()
{
ItemList = Items;
}
}
正如official document所说,模板化组件是通用类型的,那么在使用TableTemplated时,可以通过模板参数将数据从主页面传输到TableTemplate组件。
尝试使用以下代码:
TableTemplate.razor:
@typeparam TItem
<table class="table">
<thead>
<tr>@TableHeader</tr>
</thead>
<tbody>
@foreach (var item in Items)
{
<tr>@RowTemplate(item)</tr>
}
</tbody>
</table>
@code {
[Parameter]
public RenderFragment TableHeader { get; set; }
[Parameter]
public RenderFragment<TItem> RowTemplate { get; set; }
[Parameter]
public IReadOnlyList<TItem> Items { get; set; }
}
Index.razor:这里我们为每个单元格添加onclick事件。
<TableTemplate Items="pets" Context="pet">
<TableHeader>
<th>ID</th>
<th>Name</th>
<th>Class</th>
</TableHeader>
<RowTemplate >
<td @onclick="((e)=>SelectItems(pet.PetId, true))">@pet.PetId</td>
<td @onclick="((e)=>SelectItems(pet.PetId, true))">@pet.Name</td>
<td @onclick="((e)=>SelectItems(pet.PetId, true))">@pet.Class</td>
</RowTemplate>
</TableTemplate>
<button type="button" class="btn btn-sm btn-info" @onclick="showSelected">Click</button>
@code {
private List<Pet> pets = new List<Pet>()
{
new Pet { PetId = 2, Name = "Mr. Bigglesworth" },
new Pet { PetId = 4, Name = "Salem Saberhagen" },
new Pet { PetId = 7, Name = "K-9" }
};
private List<string> events = new List<string>();
private class Pet
{
public int PetId { get; set; }
public string Name { get; set; }
public string Class { get; set; }
}
void SelectItems(int petId, bool toggle)
{
var item = pets.Find(c=>c.PetId ==petId);
//If toggle then allow multiple to be selected. If class already selected then clear.
if (toggle)
{
if (item.Class == "selected")
{
item.Class = "";
}
else
{
item.Class = "selected";
}
}
else
{
foreach (var value in pets)
{
value.Class = "";
}
// set the value
item.Class = "selected";
}
}
//Function to show the selected items.
void showSelected()
{
foreach (var value in pets)
{
if (value.Class!=null && value.Class.Contains("selected"))
{
events.Add($"'{value.Name}' selected. With value: '{value.Name}'");
};
}
}
}
结果如下:
我想制作一个 table component
,使用可重复使用的多选 Titem,我设法进行了多选,但无法制作 component reusable
,有什么建议吗?
我有一个可重复使用的 table,它是我通过查看来自 Microsoft https://docs.microsoft.com/en-us/aspnet/core/blazor/components/templated-components?view=aspnetcore-5.0 的直接示例制作的
这是我的代码:
@page "/multiple"
<div class="table-responsive">
<table class="table table-sm table-bordered table-hover">
<thead class="thead-dark">
<tr>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
@if (valueList != null)
{
int count = valueList.Count;
for (var i = 0; i < count; i++)
{
int current = i; // don't use loop variable in binding
var values = valueList[current];
<tr class="@values.Class" @onclick="((e) => SelectItems(current, true))">
<td>@values.Name</td>
<td>@values.Age</td>
</tr>
}
}
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<button type="button" class="btn btn-sm btn-info" @onclick="showSelected">Click</button>
<hr />
@if (events != null)
{
<ul>
@foreach (var evt in events)
{
<li>@evt</li>
}
</ul>
}
@code
{
//Declare various lists and classes.
private List<Value> valueList;
private List<string> events = new List<string>();
class Value
{
public string Name { get; set; }
public string Age { get; set; }
public string Class { get; set; }
}
//OnInitialized function to instantiated the valueList.
protected override void OnInitialized()
{
valueList = new List<Value>();
valueList.Add(new Value()
{
Name = "James",
Age = "38"
});
valueList.Add(new Value()
{
Name = "John",
Age = "32"
});
}
//Function to set selected class on tr. Can multi-select or single via Toggle bool.
void SelectItems(int index, bool toggle)
{
var item = valueList[index];
//If toggle then allow multiple to be selected. If class already selected then clear.
if (toggle)
{
if (item.Class == "selected")
{
item.Class = "";
}
else
{
item.Class = "selected";
}
}
else
{
foreach (var value in valueList)
{
value.Class = "";
}
// set the value
item.Class = "selected";
}
}
//Function to show the selected items.
void showSelected()
{
events.Clear();
foreach (var value in valueList)
{
if (value.Class.Contains("selected"))
{
events.Add($"'{value.Name}' selected. With value: '{value.Age}'");
};
}
}
}
这个table已经是一个可重复使用的组件了,我怎样才能让它成为多选table:
<table class="@TableClass">
<thead class="@TheadClass">
<tr>
@Cabecera
</tr>
</thead>
<tbody>
@foreach (var item in ItemList)
{
<tr>@Filas(item)</tr>
}
</tbody>
<tfoot>
<tr>
@Pie
</tr>
</tfoot>
</table>
@code{
[Parameter] public string ClassTable { get; set; }
[Parameter] public string ClassThead { get; set; }
[Parameter] public RenderFragment Cabecera { get; set; }
[Parameter] public RenderFragment Pie { get; set; }
[Parameter] public RenderFragment<TItem> Filas { get; set; }
[Parameter] public IEnumerable<TItem> Items { get; set; }
IEnumerable<TItem> ItemList { get; set; }
protected override async Task OnInitializedAsync()
{
ItemList = Items;
}
}
正如official document所说,模板化组件是通用类型的,那么在使用TableTemplated时,可以通过模板参数将数据从主页面传输到TableTemplate组件。
尝试使用以下代码:
TableTemplate.razor:
@typeparam TItem
<table class="table">
<thead>
<tr>@TableHeader</tr>
</thead>
<tbody>
@foreach (var item in Items)
{
<tr>@RowTemplate(item)</tr>
}
</tbody>
</table>
@code {
[Parameter]
public RenderFragment TableHeader { get; set; }
[Parameter]
public RenderFragment<TItem> RowTemplate { get; set; }
[Parameter]
public IReadOnlyList<TItem> Items { get; set; }
}
Index.razor:这里我们为每个单元格添加onclick事件。
<TableTemplate Items="pets" Context="pet">
<TableHeader>
<th>ID</th>
<th>Name</th>
<th>Class</th>
</TableHeader>
<RowTemplate >
<td @onclick="((e)=>SelectItems(pet.PetId, true))">@pet.PetId</td>
<td @onclick="((e)=>SelectItems(pet.PetId, true))">@pet.Name</td>
<td @onclick="((e)=>SelectItems(pet.PetId, true))">@pet.Class</td>
</RowTemplate>
</TableTemplate>
<button type="button" class="btn btn-sm btn-info" @onclick="showSelected">Click</button>
@code {
private List<Pet> pets = new List<Pet>()
{
new Pet { PetId = 2, Name = "Mr. Bigglesworth" },
new Pet { PetId = 4, Name = "Salem Saberhagen" },
new Pet { PetId = 7, Name = "K-9" }
};
private List<string> events = new List<string>();
private class Pet
{
public int PetId { get; set; }
public string Name { get; set; }
public string Class { get; set; }
}
void SelectItems(int petId, bool toggle)
{
var item = pets.Find(c=>c.PetId ==petId);
//If toggle then allow multiple to be selected. If class already selected then clear.
if (toggle)
{
if (item.Class == "selected")
{
item.Class = "";
}
else
{
item.Class = "selected";
}
}
else
{
foreach (var value in pets)
{
value.Class = "";
}
// set the value
item.Class = "selected";
}
}
//Function to show the selected items.
void showSelected()
{
foreach (var value in pets)
{
if (value.Class!=null && value.Class.Contains("selected"))
{
events.Add($"'{value.Name}' selected. With value: '{value.Name}'");
};
}
}
}
结果如下: