Blazor 复选框过滤奇怪的渲染
Blazor checkbox filtering strange rendering
我有一个 CheckModel 类 列表,其属性为 int Id 和 bool IsChecked。我想根据 IsChecked 属性.
过滤它们
当我在过滤已检查项目的 foreach 循环中呈现它们时,出现错误行为。该项目已从视图中删除,但在视图中占据它位置的下方项目呈现为选中状态,而实际上它不是。
这是显示此行为的 gif:
似乎 Blazor 的渲染在某种程度上落后于复选框。
这是代码:
@page "/"
<div>
<input id="filter-collected-checkbox" type="checkbox" @bind="FilterChecked" />
<label for="filter-collected-checkbox">Filter</label>
</div>
@foreach((CheckModel item, int index) in CheckModels.Where(x=>!FilterChecked || !x.IsChecked).Select((x,i)=>(x,i)))
{
<div style="display: flex">
@item.Id
<input id="item-collected-checkbox-@index" type="checkbox" checked="@item.IsChecked" @onchange="(e)=>MarkItemCollected(e,item)"/>
</div>
}
@code {
public List<CheckModel> CheckModels { get; set; }
public bool FilterChecked { get; set; }
protected override void OnInitialized()
{
CheckModels = new List<CheckModel>();
for (int i = 0; i < 10; i++)
{
CheckModels.Add(new CheckModel() { Id = i });
}
}
private void MarkItemCollected(ChangeEventArgs e, CheckModel item)
{
item.IsChecked = (bool)e.Value;
}
}
我将 html checked-attribute 与 @onchange 一起使用的原因是因为我想在绑定发生后有一个方法。如果我将@bind=IsChecked 与@onclick=Method 一起使用,@onclick 在绑定之前被触发。
有人知道如何解决这个问题吗?
您需要为循环内容使用@key,以便渲染引擎知道哪些项目需要更新。
<div @key=@item.Id style="display: flex">
文档是here
工作REPL
仅供参考:
<div>
<input id="filter-collected-checkbox" type="checkbox" @bind="filterChecked" />
<label for="filter-collected-checkbox">Filter</label>
</div>
@foreach(var item in FilteredItems)
{
<div @key=@item.Id style="display: flex">
@item.Id
<input id="item-collected-checkbox-@item.Id" type="checkbox" @bind="@item.IsChecked" />
</div>
}
@code {
List<CheckModel> checkModels = Enumerable.Range(0,10)
.Select(i => new CheckModel() { Id = i })
.ToList();
bool filterChecked;
IEnumerable<CheckModel> FilteredItems =>
filterChecked ? checkModels.Where(x=> !x.IsChecked) : checkModels;
}
呈现 same result.
我有一个 CheckModel 类 列表,其属性为 int Id 和 bool IsChecked。我想根据 IsChecked 属性.
过滤它们当我在过滤已检查项目的 foreach 循环中呈现它们时,出现错误行为。该项目已从视图中删除,但在视图中占据它位置的下方项目呈现为选中状态,而实际上它不是。
这是显示此行为的 gif:
似乎 Blazor 的渲染在某种程度上落后于复选框。 这是代码:
@page "/"
<div>
<input id="filter-collected-checkbox" type="checkbox" @bind="FilterChecked" />
<label for="filter-collected-checkbox">Filter</label>
</div>
@foreach((CheckModel item, int index) in CheckModels.Where(x=>!FilterChecked || !x.IsChecked).Select((x,i)=>(x,i)))
{
<div style="display: flex">
@item.Id
<input id="item-collected-checkbox-@index" type="checkbox" checked="@item.IsChecked" @onchange="(e)=>MarkItemCollected(e,item)"/>
</div>
}
@code {
public List<CheckModel> CheckModels { get; set; }
public bool FilterChecked { get; set; }
protected override void OnInitialized()
{
CheckModels = new List<CheckModel>();
for (int i = 0; i < 10; i++)
{
CheckModels.Add(new CheckModel() { Id = i });
}
}
private void MarkItemCollected(ChangeEventArgs e, CheckModel item)
{
item.IsChecked = (bool)e.Value;
}
}
我将 html checked-attribute 与 @onchange 一起使用的原因是因为我想在绑定发生后有一个方法。如果我将@bind=IsChecked 与@onclick=Method 一起使用,@onclick 在绑定之前被触发。
有人知道如何解决这个问题吗?
您需要为循环内容使用@key,以便渲染引擎知道哪些项目需要更新。
<div @key=@item.Id style="display: flex">
文档是here
工作REPL
仅供参考:
<div>
<input id="filter-collected-checkbox" type="checkbox" @bind="filterChecked" />
<label for="filter-collected-checkbox">Filter</label>
</div>
@foreach(var item in FilteredItems)
{
<div @key=@item.Id style="display: flex">
@item.Id
<input id="item-collected-checkbox-@item.Id" type="checkbox" @bind="@item.IsChecked" />
</div>
}
@code {
List<CheckModel> checkModels = Enumerable.Range(0,10)
.Select(i => new CheckModel() { Id = i })
.ToList();
bool filterChecked;
IEnumerable<CheckModel> FilteredItems =>
filterChecked ? checkModels.Where(x=> !x.IsChecked) : checkModels;
}
呈现 same result.