fix(module: tree): fix IList DataSource cannot be modify in place (#3275)

* fix(module: tree): skip `ToList()` when type is `IList`

This allow DataSource to be modify by TreeNode draggable methods.

* test(module: tree): add test for TreeNode modify DataSource
This commit is contained in:
Jtfk 2023-06-04 16:30:48 +08:00 committed by GitHub
parent 1f9c539578
commit 33032f7b76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 113 additions and 2 deletions

View File

@ -713,7 +713,14 @@ namespace AntDesign
get
{
if (TreeComponent.ChildrenExpression != null)
return TreeComponent.ChildrenExpression(this)?.ToList() ?? new List<TItem>();
{
var childItems = TreeComponent.ChildrenExpression(this);
if (childItems is IList<TItem> list)
{
return list;
}
return childItems?.ToList() ?? new List<TItem>();
}
else
return new List<TItem>();
}
@ -728,7 +735,7 @@ namespace AntDesign
if (this.ParentNode != null)
return this.ParentNode.ChildDataItems;
else
return this.TreeComponent.DataSource.ToList();
return this.TreeComponent.DataSource as IList<TItem> ?? this.TreeComponent.DataSource.ToList();
}
#endregion data binding

View File

@ -0,0 +1,104 @@
@inherits AntDesignTestBase
@code {
record Item(string Name)
{
public List<Item> Children { get; set; } = new();
};
[Fact]
public async Task Parent_MoveDown_item_mutate_datasource()
{
var data = new List<Item>
{
new Item("Item 1"),
new Item("Item 2"),
};
var cut = Render<Tree<Item>>(@<Tree TItem="Item" DataSource="data"/>);
var firstItem = cut.FindComponent<TreeNode<Item>>();
var firstItemIndex = data.IndexOf(firstItem.Instance.DataItem) + 1;
firstItem.Instance.MoveDown();
var resultList = firstItem.Instance.GetParentChildDataItems();
resultList.Should().HaveElementAt(firstItemIndex, firstItem.Instance.DataItem, "DataSource should be mutated");
}
[Fact]
public async Task Parent_Remove_item_mutate_datasource()
{
var data = new List<Item>
{
new Item("Item 1"),
new Item("Item 2"),
};
var cut = Render<Tree<Item>>(@<Tree TItem="Item" DataSource="data"/>);
var firstItem = cut.FindComponent<TreeNode<Item>>();
firstItem.Instance.Remove();
data.Should().NotContain(firstItem.Instance.DataItem, "Item should be removed in DataSource");
}
[Fact]
public async Task Children_MoveDown_item_mutate_datasource()
{
var data = new List<Item>
{
new Item("Item 1")
{
Children = new List<Item>
{
new Item("Child 1-1"),
new Item("Child 1-2"),
}
},
};
var cut = Render<Tree<Item>>(
@<Tree TItem="Item"
DataSource="data"
ChildrenExpression="node => node.DataItem.Children">
</Tree>);
var treeNodes = cut.FindComponents<TreeNode<Item>>();
var childComponent = treeNodes.First(component => component.Instance.DataItem.Name.Equals("Child 1-1"));
var childItemIndex = data[0].Children.IndexOf(childComponent.Instance.DataItem) + 1;
childComponent.Instance.MoveDown();
var resultList = childComponent.Instance.GetParentChildDataItems();
resultList.Should().HaveElementAt(childItemIndex, childComponent.Instance.DataItem, "DataSource should be mutated");
}
[Fact]
public async Task Children_Remove_item_mutate_datasource()
{
var data = new List<Item>
{
new Item("Item 1")
{
Children = new List<Item>
{
new Item("Child 1-1"),
new Item("Child 1-2"),
}
},
};
var cut = Render<Tree<Item>>(
@<Tree TItem="Item"
DataSource="data"
ChildrenExpression="node => node.DataItem.Children">
</Tree>);
var treeNodes = cut.FindComponents<TreeNode<Item>>();
var childComponent = treeNodes.First(component => component.Instance.DataItem.Name.Equals("Child 1-2"));
childComponent.Instance.Remove();
data[0].Children.Should().NotContain(childComponent.Instance.DataItem, "Item should be removed in DataSource");
}
}