C# Blazor列表<;T>;更改T元素时缺少重新渲染
当我从表单组件更新对象时,我尝试更新对象列表。但如果我的对象得到了很好的更新,我的列表就不会更新 这里是我的父组件C# Blazor列表<;T>;更改T元素时缺少重新渲染,c#,blazor,C#,Blazor,当我从表单组件更新对象时,我尝试更新对象列表。但如果我的对象得到了很好的更新,我的列表就不会更新 这里是我的父组件 @inject ApiClient Api @if (normes != null) { <ul> @foreach (var item in normes) { <li @onclick="@(()=> norme = item)">@item.Name</l
@inject ApiClient Api
@if (normes != null)
{
<ul>
@foreach (var item in normes)
{
<li @onclick="@(()=> norme = item)">@item.Name</li>
}
</ul>
}
@if (norme != null)
{
<label>The bind parameter in the parent: @norme.Name</label>
<Edit @bind-Norme="norme" />
}
@code {
private List<Norme> normes { get; set; }
private Norme norme { get; set; }
protected override async Task OnInitializedAsync()
{
normes = await Api.GetAsync<List<Norme>>("norme");
}
}
@InjectApiclient Api
@如果(正常值!=null)
{
@foreach(标准中的变量项)
{
- @item.Name
}
}
@if(norme!=null)
{
父项中的bind参数:@norme.Name
}
@代码{
私有列表规范{get;set;}
私有规范规范{get;set;}
受保护的重写异步任务OnInitializedAsync()
{
normes=await-Api.GetAsync(“norme”);
}
}
我从一个api获得一个列表,当我选择一个规范时,会显示一个表单组件来编辑它
这里是我的子组件:
@inject ApiClient Api
<Loader WaitFor="localNorme">
<EditForm Model="localNorme" OnValidSubmit="OnValidSubmit">
<DataAnnotationsValidator />
@if (localNorme.Id == 0)
{
<h3>Nouvelle norme</h3>
}
else
{
<h3>Norme n° @localNorme.Id</h3>
}
<div class="btn-toolbar justify-content-end" role="toolbar">
<div class="btn-group mr-2" role="group">
<button type="submit" class="btn btn-outline-success"><i class="bi-save" /></button>
<button type="button" class="btn btn-outline-danger" @onclick="OnCancelClick"><i class="bi-x" /></button>
</div>
</div>
<div class="overflow-auto">
<div class="form-group">
<FormLabel For="@(()=>localNorme.Name)" />
<InputText @bind-Value="localNorme.Name" class="form-control" />
<ValidationMessage For="@(()=>localNorme.Name)" />
</div>
<input type="hidden" @bind-value="localNorme.Id" />
</div>
</EditForm>
<label>The bind parameter in the child: @Norme.Name</label>
</Loader>
@code {
[Parameter] public Norme Norme { get; set; }
[Parameter] public EventCallback<Norme> NormeChanged { get; set; }
private Norme localNorme;
protected override async Task OnParametersSetAsync()
{
await LoadAsync();
}
private async Task LoadAsync()
{
if (Norme.Id > 0)
{
localNorme = await Api.GetAsync<Norme>($"norme/{Norme.Id}");
}
else
{
localNorme = new Norme();
}
}
private async Task OnValidSubmit(EditContext context)
{
Norme model = context.Model as Norme;
if (model.Id > 0)
{
// Update
model = await Api.PutAsync<Norme>($"norme/{Norme.Id}", model);
}
else
{
// Create
model = await Api.PostAsync<Norme>("norme", model);
}
await NormeChanged.InvokeAsync(model); // bound object update
}
private async Task OnCancelClick()
{
await LoadAsync();
}
}
@InjectApiclient Api
@if(localNorme.Id==0)
{
新常态
}
其他的
{
Norme n°@localNorme.Id
}
子项中的bind参数:@Norme.Name
@代码{
[参数]公共规范规范{get;set;}
[参数]公共事件回调规范更改{get;set;}
私有规范本地规范;
受保护的重写异步任务OnParametersSetAsync()
{
等待LoadAsync();
}
专用异步任务LoadAsync()
{
如果(Norme.Id>0)
{
localNorme=await-Api.GetAsync($“norme/{norme.Id}”);
}
其他的
{
localNorme=新的Norme();
}
}
私有异步任务OnValidSubmit(EditContext上下文)
{
Norme model=context.model为Norme;
如果(model.Id>0)
{
//更新
model=wait Api.PutAsync($“norme/{norme.Id}”,model);
}
其他的
{
//创造
模型=等待Api.PostAsync(“标准”,模型);
}
wait NormeChanged.InvokeAsync(model);//绑定对象更新
}
专用异步任务OnCancelClick()
{
等待LoadAsync();
}
}
以下是我提交表格时的结果:
如您所见,我的列表没有更新
首先,在我的子组件中,我使用Norme参数作为表单中的模型。但我的父参数和列表在输入的OnChanged事件中更新。
因此,我在表单中插入一个localNorme作为模型,当它提交时,我使用EventCallback更新绑定参数。
在我的父级中,我的参数更新得很好,但我不知道启动列表更新时错过了什么
我尝试插入一些StateHasChanged(),但没有任何更改。如果我在父对象中更新了norme的属性,我还会检查列表是否已更新
谢谢。我想您要更新的列表是“normes” 您可以在此处设置该列表:
受保护的重写异步任务OnInitializedAsync()
{
normes=await-Api.GetAsync(“norme”);
}
仅当父对象首次添加到渲染树时才调用
您需要一种在项目发生更改时更新它的方法
简单的方法是手动绑定Edit组件,这样就可以为NormeChanged回调注册一个处理程序
<Edit Norme="norme" NormeChanged=RefreshList/>
然后RefreshList可以更新列表“normes”并刷新父组件
@inject ApiClient Api
@if (normes != null)
{
<ul>
@foreach (var item in normes)
{
<li @onclick="@(()=> norme = item)">@item.Name</li>
}
</ul>
}
@if (norme != null)
{
<label>The bind parameter in the parent: @norme.Name</label>
<Edit @bind-Norme="norme" />
}
@code {
private List<Norme> normes { get; set; }
private Norme norme { get; set; }
protected override async Task OnInitializedAsync()
{
normes = await Api.GetAsync<List<Norme>>("norme");
}
}
异步任务刷新列表(Norme-Norme)
{
normes=await-Api.GetAsync(“norme”);
StateHasChanged();
}
当然,有很多方法可以做到这一点——集中式状态、事件聚合器、消息总线——这是最简单的方法。我考虑过这个解决方案,您甚至不必将StateHasChanged()放在这里。它可以工作,但我感觉我对api进行了不必要的调用。我想没问题,但我会采取任何更优雅的解决方案;)谢谢(我会等几天再接受这个答案)哦,我明白了-很难理解这里的代码-我想我现在明白了-尝试向您呈现的列表项添加一个
@key
,@item.Name
-它可能正在更新集合,但是不改变UI,因为它是如何检测变化的@key指令在这种情况下没有影响。但是我在回调中使用真实数据(大约10k个条目)尝试了api调用,并且响应时间几乎是即时的(我的列表显示在分页表中),因此我将使用此解决方案。非常感谢。