Blazor Appstate 不更新 ChildComponent
Blazor Appstate doesn't update ChildComponent
尝试使用 AppState 传递变量 class,当调用发生在同一组件中时组件会更新,但当父级触发事件时不会发生在子组件中。
Parent
@code {
[Parameter]
public int Id { get; set; }
WikiDetailDto wikiDetail = null;
protected async override Task OnInitializedAsync()
{
Console.WriteLine("going in detail INIT");
AppState.OnCurrentWikiPageChanged += StateHasChanged;
AppState.SetCurrentWikiPage(await wikiPageService.GetDetail(Id));
wikiDetail = AppState.CurrentWikiPage;
Console.WriteLine("Retrieved WikiDetail!");
}
}
Child
<MudDrawer Anchor="Anchor.End" Open="true">
<MudDrawerHeader>Recommendations</MudDrawerHeader>
@if(AppState.CurrentWikiPage != null)
{
@(RecommendedWikiPages = CalculateReccomendedWikis(AppState.CurrentWikiPage));
if(RecommendedWikiPages != null)
{
foreach(var p in RecommendedWikiPages)
{
<MudCard>
<MudCardContent>
<MudText>@p.Name</MudText>
</MudCardContent>
</MudCard>
}
}
}
else
{
<p>Loading...</p>
}
当 AppState.CurrentWikiPage 更新时,它不会检查 cild 的 if 语句。
这里的最佳做法是什么?我不想使用级联值。
AppState
public WikiDetailDto CurrentWikiPage { get; set; }
public event Action OnCurrentWikiPageChanged;
public void SetCurrentWikiPage(WikiDetailDto wikiPage)
{
CurrentWikiPage = wikiPage;
OnCurrentWikiPageChanged?.Invoke();
}
如果我没看错你的代码,child 组件需要注册 OnCurrentWikiPageChanged
事件。
您的 child 需要如下所示:
@implements IDisposable
..... markup code
protected async override Task OnInitializedAsync()
{
AppState.OnCurrentWikiPageChanged += StateHasChanged;
}
public void Dispose()
{
AppState.OnCurrentWikiPageChanged -= StateHasChanged;
}
我个人不会 link StateHasChanged
直接到事件处理程序。这是不好的做法,因为 StateHasChanged
必须 运行 UI 上下文线程。如果事件调用者 运行ning 在另一个线程上,您将得到一个异常。我会坚持使用标准 EventHandler
。 WASM 现在可能是单线程的,但可能不会永远如此。
我的处理程序看起来像:
private void OnxxxChanged(object sender, EventArgs e)
=> this.InvokeAsync(StateHasChanged);
尝试使用 AppState 传递变量 class,当调用发生在同一组件中时组件会更新,但当父级触发事件时不会发生在子组件中。
Parent
@code {
[Parameter]
public int Id { get; set; }
WikiDetailDto wikiDetail = null;
protected async override Task OnInitializedAsync()
{
Console.WriteLine("going in detail INIT");
AppState.OnCurrentWikiPageChanged += StateHasChanged;
AppState.SetCurrentWikiPage(await wikiPageService.GetDetail(Id));
wikiDetail = AppState.CurrentWikiPage;
Console.WriteLine("Retrieved WikiDetail!");
}
}
Child
<MudDrawer Anchor="Anchor.End" Open="true">
<MudDrawerHeader>Recommendations</MudDrawerHeader>
@if(AppState.CurrentWikiPage != null)
{
@(RecommendedWikiPages = CalculateReccomendedWikis(AppState.CurrentWikiPage));
if(RecommendedWikiPages != null)
{
foreach(var p in RecommendedWikiPages)
{
<MudCard>
<MudCardContent>
<MudText>@p.Name</MudText>
</MudCardContent>
</MudCard>
}
}
}
else
{
<p>Loading...</p>
}
当 AppState.CurrentWikiPage 更新时,它不会检查 cild 的 if 语句。 这里的最佳做法是什么?我不想使用级联值。
AppState
public WikiDetailDto CurrentWikiPage { get; set; }
public event Action OnCurrentWikiPageChanged;
public void SetCurrentWikiPage(WikiDetailDto wikiPage)
{
CurrentWikiPage = wikiPage;
OnCurrentWikiPageChanged?.Invoke();
}
如果我没看错你的代码,child 组件需要注册 OnCurrentWikiPageChanged
事件。
您的 child 需要如下所示:
@implements IDisposable
..... markup code
protected async override Task OnInitializedAsync()
{
AppState.OnCurrentWikiPageChanged += StateHasChanged;
}
public void Dispose()
{
AppState.OnCurrentWikiPageChanged -= StateHasChanged;
}
我个人不会 link StateHasChanged
直接到事件处理程序。这是不好的做法,因为 StateHasChanged
必须 运行 UI 上下文线程。如果事件调用者 运行ning 在另一个线程上,您将得到一个异常。我会坚持使用标准 EventHandler
。 WASM 现在可能是单线程的,但可能不会永远如此。
我的处理程序看起来像:
private void OnxxxChanged(object sender, EventArgs e)
=> this.InvokeAsync(StateHasChanged);