Blazor中Foreach循环组件如何更新父组件列表数据?
问题描述
我在Blazor的Razor页面里有这段代码:
@foreach (AanmeldingItem ai in Aanmeldingen.Aanmeldingen) { <NieuweAanmeldingScherm Aanmelding=@ai SL=@SL /> }
组件NieuweAanmeldingScherm包含多个div和InputText用于收集数据。页面上还有一个按钮,点击后会向Aanmeldingen.Aanmeldingen(AanmeldingItem类型的列表)添加新项。
目前遇到的问题是:输入的数据无法更新到列表中的对应项。
我刚接触Blazor,将场景简化如下:
Razor页面代码:
@foreach (MyClass myclass in MyClasses) { <MyComponent Myclass=@myclass /> }
子组件MyComponent代码:
<InputText @bind-value=@myclass.item1 /> <InputText @bind-value=@myclass.item2 /> @code { [Parameter] public MyClass myclass { get; set; } }
添加按钮代码:
<div class="form-control nieuwAanmeldItem" @onclick="NieuwItem"></div>
请问如何实现让MyClasses列表同步子组件InputText中的输入信息?
解决方案
1. 确认MyClass属性可读写
首先确保MyClass的属性是可读写的,这是数据绑定的基础:
public class MyClass { public string item1 { get; set; } public string item2 { get; set; } }
如果属性是只读的,输入框内容无法同步到对象中。
2. 给foreach循环添加@key标识
Blazor需要@key来跟踪每个子组件和对应数据项的关联,避免列表变化时组件复用导致的绑定混乱。修改Razor页面的循环代码:
@foreach (MyClass myclass in MyClasses) { <MyComponent Myclass=@myclass @key=myclass /> }
如果MyClass有唯一ID属性(如Id),使用@key=myclass.Id会更可靠,避免引用重复的问题。
3. 使用可观察集合或手动触发刷新
- 推荐:使用
ObservableCollection
普通List<MyClass>不会自动通知Blazor集合变化,换成ObservableCollection可以自动触发页面更新:
using System.Collections.ObjectModel; public ObservableCollection<MyClass> MyClasses { get; set; } = new ObservableCollection<MyClass>(); private void NieuwItem() { MyClasses.Add(new MyClass()); }
- 如果用
List,手动调用StateHasChanged()
若坚持使用List,添加新项后需要强制组件刷新:
private void NieuwItem() { MyClasses.Add(new MyClass()); StateHasChanged(); }
4. 采用单向数据流(可选,更规范)
虽然直接修改引用类型对象在Blazor中可行,但通过事件回调实现单向数据流更易维护。修改子组件:
<InputText @bind-value="LocalItem1" /> <InputText @bind-value="LocalItem2" /> @code { [Parameter] public MyClass Myclass { get; set; } [Parameter] public EventCallback<MyClass> MyclassChanged { get; set; } private string LocalItem1 { get => Myclass.item1; set { Myclass.item1 = value; _ = MyclassChanged.InvokeAsync(Myclass); } } private string LocalItem2 { get => Myclass.item2; set { Myclass.item2 = value; _ = MyclassChanged.InvokeAsync(Myclass); } } }
父页面使用双向绑定:
@foreach (MyClass myclass in MyClasses) { <MyComponent @bind-Myclass=myclass @key=myclass /> }
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

