假设我有以下两个组合框(都是伪代码):
<ComboBox Data="@AllLastNames" @bind-Value="@LastName"/>
<ComboBox Data="@AllFirstNames" @bind-Value="@FirstName"/>
背后的代码是:
private string LastName { get; set; }
private string FirstName { get; set; }
private List<string> AllLastNames => _allLastNames;
private List<string> AllFirstNames => _firstNameDictionary[LastName];
好的,如果在适当的时间获得大餐,则以上所有功能都可以很好地工作AllFirstNames
,请看到它通过参考平等比较而变化,并SetParameteraAsync()
用新值调用。
那么,何时/为什么以及如何决定检查该Data=
属性以查看它们是否已更改?
LastName
这是我应该打电话的情况吗StateHasChanged()
?
Blazor 决定更新状态的方式和原因可以被视为魔法或黑匣子(更多有关状态的信息)。
但如果您对它的工作原理感兴趣,我可以举出以下示例。
状态会自动更新:
OnInitialized
、OnParametersSet
、ShouldRender
、OnAfterRender
等)您需要手动更新状态:
在您的情况下,
@bind-Value="@LastName"
作为自动更新状态的触发器,例如,当用户选择 中的项目时ComboBox
AllLastNames
,整个链都会更新,即LastName
,AllFirstNames
并且ComboBox
AllFirstNames
无需调用StateHasChanged
。注:这是我个人的偏好,但根据我的经验,使用字典而不检查存在性检查可能会导致错误,并且通常很难找到来源。
我建议检查是否存在(即使您确定它存在):
不涉及黑魔法。
当渲染实例化组件时,它会创建并维护该组件的映射属性列表。当它调用时,它会
ParameterView
从此列表中生成对象SetParametersAsync
。当渲染器渲染组件时,它会检查以确定任何子组件参数的状态是否已更改。如果有,它会调用
SetParametersAsync
子组件。注意我声明:“它调用
SetParametersAsync
”,而不是“它呈现组件”。如果该组件是一个ComponentBase
组件,那么它就会。还有其他第三方组件库组件可能会覆盖SetParametersAsync
并实现不触发StateHasChanged
.应用于每个值以检测变化的算法如下:
基本上它可以检测基元和一些值对象的变化。对于其他一切
MayHaveChanged
都会返回true
[没有机会]。注意回调和 RenderFragments 是引用对象,因此 returntrue
。在您的情况下
List<string> AllLastNames
是引用类型,因此测试失败并MayHaveChanged
返回true
。因此,如果父组件进行ComboBox
渲染,则渲染器将SetParametersAsync
调用ComboBox
.将事件处理程序EG ONCHANGE添加到您的ComboBox,该combobox将使用数据库或您正在使用的其他来源更新参考列表
每次渲染此组件时,都会在 LastName 更改时发生。
Data="@AllFirstNames"
是 Blazor 中的“复杂参数”,这意味着它将始终被视为已更改。