C# blazor中的ComponentReferenceCapture更新
在blazor示例中,我使用RenderFragment动态更新元素,并为每次更新捕获组件引用。在最初捕获元素时,它会正确地捕获组件引用。更新组件时,它将保留旧的componentReference。组件引用未正确更新 Index.razorC# blazor中的ComponentReferenceCapture更新,c#,blazor,C#,Blazor,在blazor示例中,我使用RenderFragment动态更新元素,并为每次更新捕获组件引用。在最初捕获元素时,它会正确地捕获组件引用。更新组件时,它将保留旧的componentReference。组件引用未正确更新 Index.razor @page "/" <button @onclick="AddContent">1st Update</button> <button @onclick="AddSecond
@page "/"
<button @onclick="AddContent">1st Update</button>
<button @onclick="AddSecondContent">2nd Update</button>
<button @onclick="CheckContent">Check Update</button>
@DataContent
@code {
RenderFragment DataContent { get; set; }
List<Counter> CounterReference = new List<Counter>();
void AddContent()
{
DataContent = (Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) =>
{
int seq = 0;
for(int i = 0; i < 3; i++)
{
builder.OpenComponent<Counter>(seq++);
builder.AddComponentReferenceCapture(seq++, ins => { CounterReference.Add((Counter)ins); });
builder.CloseComponent();
}
};
InvokeAsync(StateHasChanged);
}
void AddSecondContent()
{
CounterReference.Clear();
DataContent = (Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) =>
{
int seq = 0;
for (int i = 0; i < 2; i++)
{
builder.OpenComponent<Counter>(seq++);
builder.AddComponentReferenceCapture(seq++, ins => { CounterReference.Add((Counter)ins); });
builder.CloseComponent();
}
};
InvokeAsync(StateHasChanged);
}
void CheckContent()
{
Console.WriteLine();
}
}
@page "/counter"
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
public void IncrementCount()
{
currentCount++;
}
}
@page/“
第一次更新
第二次更新
检查更新
@数据内容
@代码{
RenderFragment数据内容{get;set;}
列表计数器引用=新列表();
void AddContent()
{
数据内容=(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder)=>
{
int-seq=0;
对于(int i=0;i<3;i++)
{
OpenComponent(seq++);
AddComponentReferenceCapture(seq++,ins=>{CounterReference.Add((Counter)ins);});
builder.CloseComponent();
}
};
InvokeAsync(statehaschange);
}
void AddSecondContent()
{
CounterReference.Clear();
数据内容=(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder)=>
{
int-seq=0;
对于(int i=0;i<2;i++)
{
OpenComponent(seq++);
AddComponentReferenceCapture(seq++,ins=>{CounterReference.Add((Counter)ins);});
builder.CloseComponent();
}
};
InvokeAsync(statehaschange);
}
void CheckContent()
{
Console.WriteLine();
}
}
计数器.剃须刀
@page "/"
<button @onclick="AddContent">1st Update</button>
<button @onclick="AddSecondContent">2nd Update</button>
<button @onclick="CheckContent">Check Update</button>
@DataContent
@code {
RenderFragment DataContent { get; set; }
List<Counter> CounterReference = new List<Counter>();
void AddContent()
{
DataContent = (Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) =>
{
int seq = 0;
for(int i = 0; i < 3; i++)
{
builder.OpenComponent<Counter>(seq++);
builder.AddComponentReferenceCapture(seq++, ins => { CounterReference.Add((Counter)ins); });
builder.CloseComponent();
}
};
InvokeAsync(StateHasChanged);
}
void AddSecondContent()
{
CounterReference.Clear();
DataContent = (Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) =>
{
int seq = 0;
for (int i = 0; i < 2; i++)
{
builder.OpenComponent<Counter>(seq++);
builder.AddComponentReferenceCapture(seq++, ins => { CounterReference.Add((Counter)ins); });
builder.CloseComponent();
}
};
InvokeAsync(StateHasChanged);
}
void CheckContent()
{
Console.WriteLine();
}
}
@page "/counter"
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
public void IncrementCount()
{
currentCount++;
}
}
@page”/counter
柜台
当前计数:@currentCount
点击我
@代码{
私有int currentCount=0;
公共无效增量计数()
{
currentCount++;
}
}
在上面的示例中,我已经更新了数据内容,最初,我得到的反引用计数为3。在此之后,我清除了一个反引用,并更新了数据内容。在第二种情况下,我正在渲染2个计数器组件,它们在DOM中正确渲染。但我得到的反引用计数为0。在第二次更新中,如果我没有清除反引用,则其值为3。使其保留以前的值。我希望这个值是2
我做错了什么?首先,这是一种创建组件的雄心勃勃的方法,很容易出错。大多数人犯的最大错误是使用一个变量来执行此操作。
seq++
请参见本文中的“序列号”部分,并且应使用静态递增计数。否则Blazor渲染器会对您正在更新的元素感到困惑。@Quango说了什么,但另外,当您在循环中渲染时,始终使用@key
指令来唯一标识您正在渲染的元素-依赖于“序列”并不能保证微分算法始终捕获何时放置/创建新对象。这里可能发生的情况是Blazor认为您最初创建了3个计数器,然后只删除了一个(#3)-但它可以保留其他两个,并且由于它已经为这些计数器生成了引用,因此您不会得到新的引用。出于兴趣,您使用RenderTreeBuilder
有什么原因吗?“你希望实现什么?”泉戈,谢谢。你的建议行得通。