我在blazor中有一个select控件,它显示了2个选项来对列进行排序,它表现得很好,但当我第一次选择第一个选项时,关联的@onchange事件不会触发,当我选择第二个选项,然后选择第一个时,它就工作了,我无法弄清楚这里出了什么问题
<select @onchange="@(() => SortTable(Name))" style="width: 1rem;">
<option>Sort By Ascending</option>
<option>Sort By Descending</option>
</select>
和事件回调方法-
private async Task SortTable(string columnName)
{
if (columnName != activeSortColumn)
{
isSortedAscending = true;
activeSortColumn = columnName;
}
else
{
if (isSortedAscending)
{
}
else
{
}
isSortedAscending = !isSortedAscending;
}
await SortEvent.InvokeAsync((columnName, isSortedAscending));
}
为了响应您对一些建议的请求,这是一个有两个选项的独立页面。
第一个坚持选择,但将列选择与排序方向分离。不太令人满意,因为它可能调用SortEvent.InvokeAsync((columnName, isSortedAscending));
两次。有人可能会想出一个更好的解决方案。我将它包括在内只是为了演示使用Select的UI挑战。
第二个使用下拉实现——在本例中是Bootstrap。它更优雅,当你选择专栏和方向时,你会得到一个单独的事件。
@page "/"
<h3>Column Sorting</h3>
<div class="row">
<div class="col-auto">
<span @onclick="@(() => ResetSort("Country"))">Country</span>
<select @onclick="@(() => ResetSort("Country"))" @onchange=@SortTable style="width: 1rem;">
<option value=false selected="@(!sortDescending)">Sort By Ascending</option>
<option value=true selected="@(sortDescending)">Sort By Descending</option>
</select>
</div>
<div class="col-auto">
<span @onclick="@(() => ResetSort("Continent"))">Continent</span>
<select @onclick="@(() => ResetSort("Continent"))" @onchange=@SortTable style="width: 1rem;">
<option value=false selected="@(!sortDescending)">Sort By Ascending</option>
<option value=true selected="@(sortDescending)">Sort By Descending</option>
</select>
</div>
</div>
<div class="row mt-3">
<div class="col-auto p-2 bg-dark text-white">
@(SortingColumn) : @(sortDescending ? "Sort Descending" : "Sort Ascending")
</div>
</div>
<div class="row mt-5">
<div class="col-auto" @onmouseover="@(() => ShowSorting("Country"))" @onmouseout="@(() => ShowSorting(string.Empty))">
<div class="dropdown dropdown-toggle">
Country
<span class="navbar-toggler-icon"></span>
</div>
@DropDown("Country")
</div>
<div class="col-auto">
<div class="col-auto" @onmouseover="@(() => ShowSorting("Continent"))" @onmouseout="@(() => ShowSorting(string.Empty))">
<div class="dropdown dropdown-toggle">
Continent
<span class="navbar-toggler-icon"></span>
</div>
@DropDown("Continent")
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-auto p-2 bg-dark text-white">
@(SortingColumn) : @(sortDescending ? "Sort Descending" : "Sort Ascending")
</div>
</div>
@code {
bool sortDescending;
// Set to default sort column
string SortingColumn = "Country";
// Top row code
private void ResetSort(string name)
{
if (!name.Equals(SortingColumn))
{
sortDescending = false;
SortingColumn = name;
}
}
private void SortTable(ChangeEventArgs e)
{
if (bool.TryParse(e.Value?.ToString(), out bool value))
sortDescending = value;
}
private string GetActive(string column, bool dir)
{
if (SortingColumn.Equals(column))
return dir == sortDescending ? "active" : string.Empty;
return string.Empty;
}
string SelectedColumn = string.Empty;
private void SetSorting(string column, bool descending)
{
SortingColumn = column;
sortDescending = descending;
}
private void ShowSorting(string column)
{
SelectedColumn = column;
}
private RenderFragment DropDown(string column) => (__builder) =>
{
@if (this.SelectedColumn.Equals(column))
{
<ul class="dropdown-menu show p-0">
<li class="dropdown-item @GetActive(column, false)" @onclick="() => this.SetSorting(column, false)">Ascending</li>
<li class="dropdown-item @GetActive(column, true)" @onclick="() => this.SetSorting(column, true)">Descending</li>
</ul>
}
};
}