究竟是什么触发了 Blazor 组件重绘自身?
What exactly triggers a Blazor component to redraw itself?
我有 Blazor WebAssembly 应用程序。我有一个共享模型 class 的 parent 和 child 组件。当 child 更新模型上的值时,child 会重绘自身,但 parent 不会。那么究竟是什么 触发了 Blazor 组件重绘自身呢?我找不到关于 Blazor 这个特定方面的任何文档。
我有一个 POCO 模型 class。在实际应用程序中,这来自一个单独的程序集。 Models/AwesomenessModel.cs:
namespace BlazorApp.Models {
public class AwesomenessModel {
public int? Level { get; set; }
}
}
我的索引页。 Pages/Index.剃刀:
@page "/"
@using BlazorApp.Components
@using BlazorApp.Models
<Awesomeness AwesomenessModel="@AwesomenessModel"></Awesomeness>
@code {
private AwesomenessModel AwesomenessModel = new AwesomenessModel();
}
parent class。我添加了一个重绘按钮来验证内容应该已经改变。 Components/Awesomeness.剃刀:
@using BlazorApp.Models
@if (AwesomenessModel.Level.HasValue) {
<div>Awesomeness is @AwesomenessModel.Level.Value</div>
} else {
for (int i = 0; i < 10; i++) {
<AwesomenessSelector AwesomenessModel="@AwesomenessModel" Level="@i"></AwesomenessSelector>
}
}
<div><button class="btn btn-link" @onclick="RedrawClick">Redraw</button></div>
@code {
[Parameter]
public AwesomenessModel AwesomenessModel { get; set; }
private void RedrawClick() {
this.StateHasChanged();
}
}
对 Awesomeness 模型进行实际更改的 child 组件。 Components/AwesomenessSelector.razor:
@using BlazorApp.Models
@if (!AwesomenessModel.Level.HasValue) {
<div><button class="btn btn-link" @onclick="LevelClick">@Level</button></div>
}
@code {
[Parameter]
public AwesomenessModel AwesomenessModel { get; set; }
[Parameter]
public int Level { get; set; }
private void LevelClick() {
AwesomenessModel.Level = Level;
}
}
当我 运行 应用程序并单击一个 awesomeness 级别时,该级别消失(AwesomenessSelector 组件重绘),但其余部分仍然可见并且没有 'Awesomeness is...' 消息(Awesomeness组件不更新)。如果我随后单击“重绘”按钮强制重绘 Awesomeness 组件,我会收到正确的 'Awesomeness is...' 消息。
我可能没有以正确的方式构建代码来让 parent 组件自动重绘。在这种情况下我应该如何构建它?
您需要StateHasChanged()
在不知道子项已更新的父控件上。我相信您应该在需要更新父项时触发的子项上创建一个事件。然后在事件触发时在父级上 StateHasChanged()
。所有理论,但应该有效。
子组件为 OnLevelClick 添加 EventCallback
@using BlazorApp.Models
@if (!AwesomenessModel.Level.HasValue) {
<div><button class="btn btn-link" @onclick="LevelClick">@Level</button></div>
}
@code {
[Parameter]
public AwesomenessModel AwesomenessModel { get; set; }
[Parameter]
public int Level { get; set; }
[Parameter]
public EventCallback<string> OnLevelClick { get; set; }
private void LevelClick() {
AwesomenessModel.Level = Level;
OnLevelClick.InvokeAsync();
}
}
父组件为 OnLevelClick 添加处理程序
@using BlazorApp.Models
@if (AwesomenessModel.Level.HasValue) {
<div>Awesomeness is @AwesomenessModel.Level.Value</div>
} else {
for (int i = 0; i < 10; i++) {
<AwesomenessSelector AwesomenessModel="@AwesomenessModel" Level="@i" @OnLevelClick="OnLevelClick"></AwesomenessSelector>
}
}
@code {
[Parameter]
public AwesomenessModel AwesomenessModel { get; set; }
private void OnLevelClick() {
this.StateHasChanged();
}
}
希望这对您有所帮助
我有 Blazor WebAssembly 应用程序。我有一个共享模型 class 的 parent 和 child 组件。当 child 更新模型上的值时,child 会重绘自身,但 parent 不会。那么究竟是什么 触发了 Blazor 组件重绘自身呢?我找不到关于 Blazor 这个特定方面的任何文档。
我有一个 POCO 模型 class。在实际应用程序中,这来自一个单独的程序集。 Models/AwesomenessModel.cs:
namespace BlazorApp.Models {
public class AwesomenessModel {
public int? Level { get; set; }
}
}
我的索引页。 Pages/Index.剃刀:
@page "/"
@using BlazorApp.Components
@using BlazorApp.Models
<Awesomeness AwesomenessModel="@AwesomenessModel"></Awesomeness>
@code {
private AwesomenessModel AwesomenessModel = new AwesomenessModel();
}
parent class。我添加了一个重绘按钮来验证内容应该已经改变。 Components/Awesomeness.剃刀:
@using BlazorApp.Models
@if (AwesomenessModel.Level.HasValue) {
<div>Awesomeness is @AwesomenessModel.Level.Value</div>
} else {
for (int i = 0; i < 10; i++) {
<AwesomenessSelector AwesomenessModel="@AwesomenessModel" Level="@i"></AwesomenessSelector>
}
}
<div><button class="btn btn-link" @onclick="RedrawClick">Redraw</button></div>
@code {
[Parameter]
public AwesomenessModel AwesomenessModel { get; set; }
private void RedrawClick() {
this.StateHasChanged();
}
}
对 Awesomeness 模型进行实际更改的 child 组件。 Components/AwesomenessSelector.razor:
@using BlazorApp.Models
@if (!AwesomenessModel.Level.HasValue) {
<div><button class="btn btn-link" @onclick="LevelClick">@Level</button></div>
}
@code {
[Parameter]
public AwesomenessModel AwesomenessModel { get; set; }
[Parameter]
public int Level { get; set; }
private void LevelClick() {
AwesomenessModel.Level = Level;
}
}
当我 运行 应用程序并单击一个 awesomeness 级别时,该级别消失(AwesomenessSelector 组件重绘),但其余部分仍然可见并且没有 'Awesomeness is...' 消息(Awesomeness组件不更新)。如果我随后单击“重绘”按钮强制重绘 Awesomeness 组件,我会收到正确的 'Awesomeness is...' 消息。
我可能没有以正确的方式构建代码来让 parent 组件自动重绘。在这种情况下我应该如何构建它?
您需要StateHasChanged()
在不知道子项已更新的父控件上。我相信您应该在需要更新父项时触发的子项上创建一个事件。然后在事件触发时在父级上 StateHasChanged()
。所有理论,但应该有效。
子组件为 OnLevelClick 添加 EventCallback
@using BlazorApp.Models
@if (!AwesomenessModel.Level.HasValue) {
<div><button class="btn btn-link" @onclick="LevelClick">@Level</button></div>
}
@code {
[Parameter]
public AwesomenessModel AwesomenessModel { get; set; }
[Parameter]
public int Level { get; set; }
[Parameter]
public EventCallback<string> OnLevelClick { get; set; }
private void LevelClick() {
AwesomenessModel.Level = Level;
OnLevelClick.InvokeAsync();
}
}
父组件为 OnLevelClick 添加处理程序
@using BlazorApp.Models
@if (AwesomenessModel.Level.HasValue) {
<div>Awesomeness is @AwesomenessModel.Level.Value</div>
} else {
for (int i = 0; i < 10; i++) {
<AwesomenessSelector AwesomenessModel="@AwesomenessModel" Level="@i" @OnLevelClick="OnLevelClick"></AwesomenessSelector>
}
}
@code {
[Parameter]
public AwesomenessModel AwesomenessModel { get; set; }
private void OnLevelClick() {
this.StateHasChanged();
}
}
希望这对您有所帮助