Blazor - 为什么双向绑定适用于 List 而不是自定义组件中的 String?
Blazor - why does two way binding work for List but not String in custom component?
所有关于使用双向绑定的文档都声称,为了在自定义组件中进行双向绑定,您需要使用 EventCallback。然而,当使用 List 时,它会自动工作。我想知道为什么?
示例页面 index.razor:
@page "/"
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
<SurveyPrompt ListOfValues="@ListOfValues" StringValue="@StringValue" />
<div @onclick="WriteValues">then click me</div>
@code {
List<string> ListOfValues { get; set; } = new();
public string StringValue { get; set; } = "";
private void WriteValues()
{
foreach(var v in ListOfValues){
Console.WriteLine($"ListOfValues: {v}");
}
Console.WriteLine($"StringValue: {StringValue}");
}
}
示例组件 SurveyPrompt.razor:
<div class="alert alert-secondary mt-4">
<div @onclick="bubu">click me</div>
</div>
@code {
[Parameter] public List<string> ListOfValues { get; set; } = new();
[Parameter] public string StringValue { get; set; } = "";
private void bubu()
{
ListOfValues.Add("First Value set in a component");
ListOfValues.Add("Second Value set in a component");
StringValue = "A Value set in a component";
}
}
当 运行 应用程序点击“点击我”,然后点击“然后点击我”时,控制台将显示 ListOfValues
变量的值在 index.razor 中已填写 SurveyPrompt.razor 但 StringValue
仍为空
页面外观:
单击“单击我”然后单击“然后单击我”后控制台的外观:
在 List<T>
的情况下,您观察到的不是绑定效果。发生的情况是,在您的 index.razor
页面中,您创建了一个列表 (ListOfValues),然后将其传递给您的 SurveyPrompt
。请注意,您不复制列表,而是通过引用传递它。 index.razor
和 SurveyPrompt
都“共享”同一个列表实例。因此,当您对列表进行更改时,它们对保持对它的引用的所有内容都是可见的。
不过,字符串是不可变的。当你改变字符串时,你并没有修改原来的字符串,而是在内存中创建一个新的字符串来替换旧的字符串。结果,修改后,index.razor
和SurveyPrompt
有两个单独的字符串。
所有关于使用双向绑定的文档都声称,为了在自定义组件中进行双向绑定,您需要使用 EventCallback。然而,当使用 List 时,它会自动工作。我想知道为什么?
示例页面 index.razor:
@page "/"
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
<SurveyPrompt ListOfValues="@ListOfValues" StringValue="@StringValue" />
<div @onclick="WriteValues">then click me</div>
@code {
List<string> ListOfValues { get; set; } = new();
public string StringValue { get; set; } = "";
private void WriteValues()
{
foreach(var v in ListOfValues){
Console.WriteLine($"ListOfValues: {v}");
}
Console.WriteLine($"StringValue: {StringValue}");
}
}
示例组件 SurveyPrompt.razor:
<div class="alert alert-secondary mt-4">
<div @onclick="bubu">click me</div>
</div>
@code {
[Parameter] public List<string> ListOfValues { get; set; } = new();
[Parameter] public string StringValue { get; set; } = "";
private void bubu()
{
ListOfValues.Add("First Value set in a component");
ListOfValues.Add("Second Value set in a component");
StringValue = "A Value set in a component";
}
}
当 运行 应用程序点击“点击我”,然后点击“然后点击我”时,控制台将显示 ListOfValues
变量的值在 index.razor 中已填写 SurveyPrompt.razor 但 StringValue
仍为空
页面外观:
单击“单击我”然后单击“然后单击我”后控制台的外观:
在 List<T>
的情况下,您观察到的不是绑定效果。发生的情况是,在您的 index.razor
页面中,您创建了一个列表 (ListOfValues),然后将其传递给您的 SurveyPrompt
。请注意,您不复制列表,而是通过引用传递它。 index.razor
和 SurveyPrompt
都“共享”同一个列表实例。因此,当您对列表进行更改时,它们对保持对它的引用的所有内容都是可见的。
不过,字符串是不可变的。当你改变字符串时,你并没有修改原来的字符串,而是在内存中创建一个新的字符串来替换旧的字符串。结果,修改后,index.razor
和SurveyPrompt
有两个单独的字符串。