我目前正在开发一个显示一些电影的应用程序。我有一个API,可以成功地检索电影,还可以选择按特定类型获取电影。为此,我创建了一个选择元素,其中动态加载了不同的流派。当点击其中一个流派时,我想使用API更新电影,只获取所选流派的电影。
不幸的是,当我选择一个选项时,什么都不会发生。请注意,我已经确认API调用是有效的,所以它必须是此代码中的某些内容。这是HTML元素:
<div class="content px-sm-3">
<select>
<option onselect="async () => await changeMoviesByGenre('None')" value="None">None</option>
@foreach (var genre in genres)
{
<option value=@genre onselect="async () => await changeMoviesByGenre(genre)">@genre</option>
}
</select>
</div>
这就是应该调用的函数:
private async Task changeMoviesByGenre(string genre) {
if (genre == "None") {
movies = await MovieClient.Movies.GetAll();
}
else {
movies = await MovieClient.Movies.GetAllMoviesByGenre(genre);
}
}
OnSelect
并不是你想象的那样。当你在Input
元素中选择文本时,它会被触发。
更简单的方法(正如你在回答你的答案时所涉及的,为了完整起见,我在答案中包含了一个完整的工作页面(是:
@page "/Test"
<div class="content px-sm-3 m-2">
<select @onchange="OnChange">
<option value="None">None</option>
@foreach (var genre in genres)
{
<option value="@genre">@genre</option>
}
</select>
</div>
<div class="m-2">Selected: @SelectedGenre</div>
@code {
private List<string> genres
=> new List<string>() { "Rock", "Folk", "Blues", "Pop" };
private string SelectedGenre = string.Empty;
private async Task OnChange(ChangeEventArgs e)
{
var selected = e.Value.ToString();
SelectedGenre = "Getting it, just wait!!!";
await Task.Delay(3000);
if (selected.Equals("None", StringComparison.CurrentCultureIgnoreCase))
this.SelectedGenre = "Give it another Go!";
else
this.SelectedGenre = selected;
}
}
@Onxxxx(例如@OnChange和@OnClick(是UI事件。在组件上重新渲染之前,它们由UI进程运行。任务事件处理程序由UI运行,并在更新UI之前等待Task
。void事件处理程序由UI进程启动,如果/当它产生更新UI(更加复杂和不可预测(。您可以根据需要使用以下代码模式:
async void MyEventHander() {}` //for handlers that need to do async work and you don't need the UI process to wait on the completion of the handler.
async Task MyEventHander() {}` //for handlers that need to complete before re-rendering.
void MyEventHander() {}` //for handlers with no async work.
在我的示例中,我添加了await Task.Delay(1000);
来模拟异步数据库调用,这样我就可以将处理程序声明为async
。
注:
OnChange
中的e
是一个对象,因此您可以将其强制转换为您所期望的- 初始化时已选择None,因此如果您先选择它,则不会有
OnChange
,因为没有任何更改
请参阅Ms-Docs-Blazor事件处理。
我设法解决了这个问题。如果你有和我一样的问题,我用这个例子解决了它。我不知道为什么它有效,但它确实有效。
我没有使用foreach中的值,而是使用ChangedEventArgs参数。我还将onchange设置为Select元素,而不是Options元素。这就是我的代码现在的样子:
<div class="content px-sm-3">
<select @onchange=@changeMovies>
<option value="None"> None </option>
@foreach (var genre in genres) {
<option value=@genre> @genre </option>
}
</select>
</div>
这是被调用的新函数(请注意,这必须是一项任务,否则页面不会更新(
private async Task changeMovies(ChangeEventArgs e) {
string selectedGenre = e.Value.ToString();
if (selectedGenre == "None") {
movies = await MovieClient.Movies.GetAll();
}
else {
movies = await MovieClient.Movies.GetAllMoviesByGenre(selectedGenre);
}
}