是什么导致 if/else 表达式被重新计算?

What causes if/else expressions to be re-evaluated?

使用 Blazor 托管模板,在我的 MainLayout.cshtml 中,我有类似的东西:

@inject UserInfo userInfo
@if(userInfo.Name == "bob")
{
    <div class="login-panel">
        <p>Hi Bob!</p>
    </div>
}
else
{
    <LoginPanel />
}

然后在一个单独的 Login.cshtml:

@inject UserInfo userInfo
async void Login()
{
    userInfo.Name = "bob";
}

但是登录不会导致 MainLayout.cshtml 中的 'login-panel' 发生变化。如果所有内容都在一个文件中并且我只检查特定变量是否为 null(请参阅 ),我能够让它工作,所以我假设 Blazor 框架有特定的标准,非法页面重新评估此类块。这是准确的吗?如果是这样,强制重新评估的最佳方法是什么?

编辑:我又玩了一会儿,最终发现了 StateHasChanged protected 成员函数,我假设它是在 Init 完成后调用的,这就是为什么前面的例子有效。我认为一个可行的解决方案是让我的 UserInfo 对象实现 INotifyPropertyChanged,然后在 MainLayout.cshtml 中注册一个更改处理程序以调用 StateHasChanged() 以获取需要在登录状态时更新的视图变化。

是的。 Blazor 使用称为 StateHasChanged 的东西,就像 INotifyPropertyChanged.

然而不同的是,在 XAML 框架中 XAML 更新那些调用了 INotifyPropertyChanged 的属性,但是在 Razor 中,当调用 StateHasChanged 时,UI 框架将刷新组件的整个 UI 树(至少到现在为止) 元素是驻留的。 如果不是你做的,那么谁调用了 StateHasChanged。当一个元素获得输入(您正在单击一个按钮)时,blazor 将自动设置引擎盖下的 StateHasChanged

更多阅读

https://github.com/aspnet/Blazor/issues/409

https://learn-blazor.com/pages/data-binding/

https://github.com/aspnet/Blazor/issues/359

https://github.com/aspnet/Blazor/issues/407