Blazor 组件列表,从列表中删除时从组件转移值
Blazor List of components, shift values from components when removed from list
我正在尝试了解我在 blazor 3.1 中遇到的这个问题,感谢任何可以向我解释的人。
- 我有一个项目清单。
- 我通过遍历列表来创建子组件。
- 每个组件都显示一个私有的 bool (IsSomething) 值,可以通过按钮进行切换。
- 有一个关闭按钮 (EventCallback) 可以从父级的列表中删除该项目,我不明白为什么其余组件的 bool 值会发生变化。
例如:
[真] [假] [假]
删除列表中的第一项(本例中为真)给出
[真] [假]
我在期待
[假] [假]
如果组件重新初始化或其他原因,如果所有布尔值都为假,我会理解,但这种行为让我感到难过。
Index.razor
@using ListComponentIssue.Shared
<h1>List Component Issue</h1>
@if (listOfItems != null)
{
<div style="display:flex; flex-direction:row;">
@foreach (var item in listOfItems)
{
<MyComponent ThisItem="@item" Close="close"></MyComponent>
}
</div>
}
Index.razor.cs
{
private List<Item> listOfItems = new List<Item>();
protected override void OnInitialized()
{
base.OnInitialized();
listOfItems.Add(
new Item()
{
Id = "1",
Title = "First"
}
);
listOfItems.Add(
new Item()
{
Id = "2",
Title = "Second"
}
);
listOfItems.Add(
new Item()
{
Id = "3",
Title = "Third"
}
);
listOfItems.Add(
new Item()
{
Id = "4",
Title = "Fourth"
}
);
listOfItems.Add(
new Item()
{
Id = "5",
Title = "Fifth"
}
);
}
public void close(Item itemToRemove)
{
listOfItems.Remove(itemToRemove);
}
}
MyComponent.razor
<div style="margin:5px;">
@ThisItem.Title is @isSomething
</div>
<div>
<button @onclick="toggleBool">Toggle bool</button>
<button @onclick="() => CloseToParent(ThisItem)">close</button>
</div>
</div>
@code {
private bool isSomething { get; set; }
[Parameter]
public Item ThisItem { get; set; }
[Parameter]
public EventCallback<Item> Close { get; set; }
private void toggleBool()
{
isSomething = !isSomething;
}
public async Task CloseToParent(Item itemToClose)
{
await Close.InvokeAsync(itemToClose);
}
public class Item
{
public string Id { get; set; }
public string Title { get; set; }
}
}
在另一个项目中,我使用 Radzen Dropdown 多 select 组件和来自右侧组件的 selected 项目 shift/merge。
例如:
[selected:1] [selected:2,3]
我删除了第一个组件,结果是
[selected:1,2,3]
删除右侧的组件不会更改左侧的组件。
我的目标是让用户能够动态地添加和删除组件。
也许我的整个方法是错误的...任何建议表示赞赏
在循环内的组件上使用 @key
。这有助于渲染引擎了解更新了哪些元素。
<MyComponent @key=@item ThisItem="@item" Close="close" />
Index.razor
<h1>List Component Issue</h1>
<div style="display:flex; flex-direction:row;">
@foreach (var item in listOfItems)
{
<MyComponent @key=@item ThisItem="@item" OnClose="OnCloseClicked" />
}
</div>
Index.razor.cs
public partial class Index
{
private List<Item> listOfItems;
public Index()
{
listOfItems = new(5)
{
new() {Id = "1", Title = "First"},
new() {Id = "2", Title = "Second"},
new() {Id = "3", Title = "Third"},
new() {Id = "4", Title = "Fourth"},
new() {Id = "5", Title = "Fifth"}
};
}
public void OnCloseClicked(Item itemToRemove)
=> listOfItems.Remove(itemToRemove);
}
MyComponent.razor
<div>
<div style="margin:5px;">
@ThisItem.Title is @isSomething
</div>
<div>
<button @onclick=ToggleBool>Toggle</button>
<button @onclick=CloseToParent>close</button>
</div>
</div>
@code {
private bool isSomething;
[Parameter]
public Item ThisItem { get; set; }
[Parameter]
public EventCallback<Item> OnClose { get; set; }
private void ToggleBool() => isSomething = !isSomething;
public async Task CloseToParent() => await OnClose.InvokeAsync(ThisItem);
}
我想知道这是否是经典的 c# lambda 捕获问题。尝试
@foreach (var item in listOfItems)
{
var temp = item;
<MyComponent ThisItem="@temp" Close="close"></MyComponent>
}
我正在尝试了解我在 blazor 3.1 中遇到的这个问题,感谢任何可以向我解释的人。
- 我有一个项目清单。
- 我通过遍历列表来创建子组件。
- 每个组件都显示一个私有的 bool (IsSomething) 值,可以通过按钮进行切换。
- 有一个关闭按钮 (EventCallback) 可以从父级的列表中删除该项目,我不明白为什么其余组件的 bool 值会发生变化。
[真] [假] [假]
删除列表中的第一项(本例中为真)给出
[真] [假]
我在期待
[假] [假]
如果组件重新初始化或其他原因,如果所有布尔值都为假,我会理解,但这种行为让我感到难过。
Index.razor
@using ListComponentIssue.Shared
<h1>List Component Issue</h1>
@if (listOfItems != null)
{
<div style="display:flex; flex-direction:row;">
@foreach (var item in listOfItems)
{
<MyComponent ThisItem="@item" Close="close"></MyComponent>
}
</div>
}
Index.razor.cs
{
private List<Item> listOfItems = new List<Item>();
protected override void OnInitialized()
{
base.OnInitialized();
listOfItems.Add(
new Item()
{
Id = "1",
Title = "First"
}
);
listOfItems.Add(
new Item()
{
Id = "2",
Title = "Second"
}
);
listOfItems.Add(
new Item()
{
Id = "3",
Title = "Third"
}
);
listOfItems.Add(
new Item()
{
Id = "4",
Title = "Fourth"
}
);
listOfItems.Add(
new Item()
{
Id = "5",
Title = "Fifth"
}
);
}
public void close(Item itemToRemove)
{
listOfItems.Remove(itemToRemove);
}
}
MyComponent.razor
<div style="margin:5px;">
@ThisItem.Title is @isSomething
</div>
<div>
<button @onclick="toggleBool">Toggle bool</button>
<button @onclick="() => CloseToParent(ThisItem)">close</button>
</div>
</div>
@code {
private bool isSomething { get; set; }
[Parameter]
public Item ThisItem { get; set; }
[Parameter]
public EventCallback<Item> Close { get; set; }
private void toggleBool()
{
isSomething = !isSomething;
}
public async Task CloseToParent(Item itemToClose)
{
await Close.InvokeAsync(itemToClose);
}
public class Item
{
public string Id { get; set; }
public string Title { get; set; }
}
}
在另一个项目中,我使用 Radzen Dropdown 多 select 组件和来自右侧组件的 selected 项目 shift/merge。
例如:
[selected:1] [selected:2,3]
我删除了第一个组件,结果是
[selected:1,2,3]
删除右侧的组件不会更改左侧的组件。
我的目标是让用户能够动态地添加和删除组件。
也许我的整个方法是错误的...任何建议表示赞赏
在循环内的组件上使用 @key
。这有助于渲染引擎了解更新了哪些元素。
<MyComponent @key=@item ThisItem="@item" Close="close" />
Index.razor
<h1>List Component Issue</h1>
<div style="display:flex; flex-direction:row;">
@foreach (var item in listOfItems)
{
<MyComponent @key=@item ThisItem="@item" OnClose="OnCloseClicked" />
}
</div>
Index.razor.cs
public partial class Index
{
private List<Item> listOfItems;
public Index()
{
listOfItems = new(5)
{
new() {Id = "1", Title = "First"},
new() {Id = "2", Title = "Second"},
new() {Id = "3", Title = "Third"},
new() {Id = "4", Title = "Fourth"},
new() {Id = "5", Title = "Fifth"}
};
}
public void OnCloseClicked(Item itemToRemove)
=> listOfItems.Remove(itemToRemove);
}
MyComponent.razor
<div>
<div style="margin:5px;">
@ThisItem.Title is @isSomething
</div>
<div>
<button @onclick=ToggleBool>Toggle</button>
<button @onclick=CloseToParent>close</button>
</div>
</div>
@code {
private bool isSomething;
[Parameter]
public Item ThisItem { get; set; }
[Parameter]
public EventCallback<Item> OnClose { get; set; }
private void ToggleBool() => isSomething = !isSomething;
public async Task CloseToParent() => await OnClose.InvokeAsync(ThisItem);
}
我想知道这是否是经典的 c# lambda 捕获问题。尝试
@foreach (var item in listOfItems)
{
var temp = item;
<MyComponent ThisItem="@temp" Close="close"></MyComponent>
}