如何更改循环内声明的变量?
How to change a variable declared inside a loop?
考虑以下代码:
在MyPage.razor中:
<ul>
@foreach (var item in myList)
{
var theBool = false;
<li>
<span>For @item, theBool is @theBool</span>
(<a href="" @onclick="@(e => theBool = !theBool)">Reverse bool for @item</a>)
</li>
}
</ul>
@code {
List<string> myList = new() { "item1", "item2", "item3", "item4", "item5", };
}
... 产生以下输出:
我希望点击 link 会切换前面的 bool 值,因此它显示“True”而不是“False”。它根本不起作用,变量似乎已更改,但 UI(<span>
)未刷新。在 Blazor Webassembly 中实现这个的好方法是什么?
(我希望不要被迫使用 @code
部分:就可维护性而言,这将是一个主要的代码开销)。
更新 1
这就是我想要实现的目标:
单击 link(在组件外部)必须更改组件的参数(以更改组件行为):
<ul>
@foreach (var item in myList)
{
var theBool = false;
<li>
<a href="" @onclick="@(e => theBool = !theBool)">Show/Hide details</a>
<MyCoolComponent DisplayDetails="@theBool"></MyCoolComponent>
</li>
}
</ul>
As theBool is captured by the lambda, I expected it still exists after le loop.
没错...
@PanagiotisKanavos : Do you mean that Blazor only subscribe for Ui refresh on fields and not variables ?
每次点击锚元素,框架会自动调用StateHasChanged方法,重新渲染UI,但是看不到变化,和开始时一样你得到的循环 var theBool = false;
因此,<span>For @item, theBool is @theBool</span>
被重新渲染为:
<span>For item2, theBool is false</span>
如果您点击了第二个项目。
您的代码将永远无法工作,因为在循环的每次迭代中,局部变量 theBool 都设置为 false;那就是你看不到 UI...
上的变化
你可以这样解决:
<ul>
@foreach (var item in Items)
{
<li>
<span>For @item.Name, item.IsSelected is @item.IsSelected</span>
(<a href="" @onclick="@(e => { item.IsSelected = !item.IsSelected; })">Reverse bool for @item.Name</a>)
</li>
}
</ul>
@code {
private List<Item> Items = Enumerable.Range(1, 5).Select(i => new Item { Name = $"item{i}" }).ToList();
public class Item
{
public string Name { get; set; }
public bool IsSelected { get; set; }
}
}
复制并测试...
每次迭代都会丢失布尔值。使用字典而不是列表将值存储在一起。
键是字符串,值是布尔值:
<ul>
@foreach (var item in myList)
{
<li>
<span>For @item.Key, theBool is @item.Value</span>
(<a href="" @onclick="@(() => myList[item.Key] = !myList[item.Key])">
Reverse bool for @item.Key
</a>)
</li>
}
</ul>
@code {
Dictionary<string, bool> myList = new()
{
{"item1", false},
{"item2", false},
{"item3", false},
{"item4", false},
{"item5", false}
};
}
当您通过点击更新布尔值时,该值将与其键一起存储。
考虑以下代码:
在MyPage.razor中:
<ul>
@foreach (var item in myList)
{
var theBool = false;
<li>
<span>For @item, theBool is @theBool</span>
(<a href="" @onclick="@(e => theBool = !theBool)">Reverse bool for @item</a>)
</li>
}
</ul>
@code {
List<string> myList = new() { "item1", "item2", "item3", "item4", "item5", };
}
... 产生以下输出:
我希望点击 link 会切换前面的 bool 值,因此它显示“True”而不是“False”。它根本不起作用,变量似乎已更改,但 UI(<span>
)未刷新。在 Blazor Webassembly 中实现这个的好方法是什么?
(我希望不要被迫使用 @code
部分:就可维护性而言,这将是一个主要的代码开销)。
更新 1
这就是我想要实现的目标: 单击 link(在组件外部)必须更改组件的参数(以更改组件行为):
<ul>
@foreach (var item in myList)
{
var theBool = false;
<li>
<a href="" @onclick="@(e => theBool = !theBool)">Show/Hide details</a>
<MyCoolComponent DisplayDetails="@theBool"></MyCoolComponent>
</li>
}
</ul>
As theBool is captured by the lambda, I expected it still exists after le loop.
没错...
@PanagiotisKanavos : Do you mean that Blazor only subscribe for Ui refresh on fields and not variables ?
每次点击锚元素,框架会自动调用StateHasChanged方法,重新渲染UI,但是看不到变化,和开始时一样你得到的循环 var theBool = false;
因此,<span>For @item, theBool is @theBool</span>
被重新渲染为:
<span>For item2, theBool is false</span>
如果您点击了第二个项目。
您的代码将永远无法工作,因为在循环的每次迭代中,局部变量 theBool 都设置为 false;那就是你看不到 UI...
上的变化你可以这样解决:
<ul>
@foreach (var item in Items)
{
<li>
<span>For @item.Name, item.IsSelected is @item.IsSelected</span>
(<a href="" @onclick="@(e => { item.IsSelected = !item.IsSelected; })">Reverse bool for @item.Name</a>)
</li>
}
</ul>
@code {
private List<Item> Items = Enumerable.Range(1, 5).Select(i => new Item { Name = $"item{i}" }).ToList();
public class Item
{
public string Name { get; set; }
public bool IsSelected { get; set; }
}
}
复制并测试...
每次迭代都会丢失布尔值。使用字典而不是列表将值存储在一起。
键是字符串,值是布尔值:
<ul>
@foreach (var item in myList)
{
<li>
<span>For @item.Key, theBool is @item.Value</span>
(<a href="" @onclick="@(() => myList[item.Key] = !myList[item.Key])">
Reverse bool for @item.Key
</a>)
</li>
}
</ul>
@code {
Dictionary<string, bool> myList = new()
{
{"item1", false},
{"item2", false},
{"item3", false},
{"item4", false},
{"item5", false}
};
}
当您通过点击更新布尔值时,该值将与其键一起存储。